]> icculus.org git repositories - taylor/freespace2.git/blob - src/graphics/tmapgenericscans.cpp
The Great Newline Fix
[taylor/freespace2.git] / src / graphics / tmapgenericscans.cpp
1 /*
2  * $Logfile: /Freespace2/code/Graphics/TmapGenericScans.cpp $
3  * $Revision$
4  * $Date$
5  * $Author$
6  *
7  * Some code for generic scanlines.  This isn't used, it is just
8  * basically a dump area for inner loops I was experimenting with.
9  * this entire file is #ifdef 0'd out.
10  *
11  * $Log$
12  * Revision 1.2  2002/05/07 03:16:45  theoddone33
13  * The Great Newline Fix
14  *
15  * Revision 1.1.1.1  2002/05/03 03:28:09  root
16  * Initial import.
17  *
18  * 
19  * 2     10/07/98 10:53a Dave
20  * Initial checkin.
21  * 
22  * 1     10/07/98 10:49a Dave
23  * 
24  * 7     4/24/97 4:45p John
25  * Added tiled texture mappers for 64x64, 128x128, and 256x256 textures.
26  * 
27  * 6     4/24/97 3:01p John
28  * added code to not crash on non-256x256 textures.
29  * 
30  * 5     3/14/97 3:55p John
31  * Made tiled tmapper not always be zbuffered.
32  * 
33  * 4     3/13/97 10:32a John
34  * Added code for tiled 256x256 textures in certain models.
35  * 
36  * 3     3/10/97 5:20p John
37  * Differentiated between Gouraud and Flat shading.  Since we only do flat
38  * shading as of now, we don't need to interpolate L in the outer loop.
39  * This should save a few percent.
40  * 
41  * 2     12/10/96 10:37a John
42  * Restructured texture mapper to remove some overhead from each scanline
43  * setup.  This gave about a 30% improvement drawing trans01.pof, which is
44  * a really complex model.  In the process, I cleaned up the scanline
45  * functions and separated them into different modules for each pixel
46  * depth.   
47  *
48  * $NoKeywords: $
49  */
50
51 #include "3d.h"
52 #include "2d.h"
53 #include "tmapper.h"
54 #include "tmapscanline.h"
55 #include "floating.h"
56 #include "palman.h"
57 #include "fix.h"
58
59 #pragma warning(disable:4410)
60  
61
62
63 #if 0
64 #include "3d.h"
65 #include "2d.h"
66 #include "tmapper.h"
67 #include "tmapscanline.h"
68 #include "floating.h"
69 #include "palman.h"
70 #include "fix.h"
71
72 #pragma warning(disable:4410)
73
74 // These must be global because I use them in assembly
75 // code that uses the EBP register, so the variables 
76 // can't be accessed off the stack.
77 int _fx_u, _fx_v, _fx_w, _fx_l;
78 int _fx_u_right, _fx_v_right, _fx_w_right;
79 int _fx_du, _fx_dv, _fx_dw, _fx_dl;
80 uint _fx_destptr,_fx_srcptr, light_table;
81 int V0, U0, DU1, DV1, DZ1;
82 int _loop_count,num_big_steps;
83 int num_left_over;
84
85 int rgbtable_inited = 0;
86 uint rgbtable1[512];
87 uint rgbtable2[512];
88 uint rgbtable3[512];
89
90 void rgbtable_init()
91 {
92         int i,v;
93         rgbtable_inited = 1;
94         for (i=0; i<512; i++ )  {
95                 v = i - 128;
96                 if ( v < 0 ) v = 0;
97                 else if ( v > 255 ) v = 255;
98                 rgbtable1[i] = v;
99                 rgbtable2[i] = v<<8;
100                 rgbtable3[i] = v<<16;
101         }
102 }
103
104
105 void asm_tmap_scanline_lln();
106 void asm_tmap_scanline_lln_tiled();
107
108 void tmapscan_lln8( int lx, int rx, int y, vertex *p, vertex *dp,  vertex * rp,uint flags )
109 {
110         Tmap1.dest_row_data = GR_SCREEN_PTR(ubyte,lx,y);
111         Tmap1.loop_count = rx - lx;
112         Tmap1.pixptr = (unsigned char *)tmap_bitmap->data;
113         Tmap1.bp = tmap_bitmap;
114         Tmap1.src_offset = tmap_bitmap->w;
115
116         Tmap1.fx_u = fl2f(p->u);
117         Tmap1.fx_v = fl2f(p->v);
118         Tmap1.fx_l = fl2f(p->l*32.0); 
119         Tmap1.fx_dl_dx = fl2f(dp->l*32.0);
120         Tmap1.fx_du_dx = fl2f(dp->u);
121         Tmap1.fx_dv_dx = fl2f(dp->v);
122         Tmap1.fx_u_right = fl2f(rp->u);
123         Tmap1.fx_v_right = fl2f(rp->v);
124
125         asm_tmap_scanline_lln();
126 }
127
128 extern void asm_tmap_scanline_lnt();
129
130 void tmapscan_lnt8( int lx, int rx, int y, vertex *p, vertex *dp,  vertex * rp,uint flags )
131 {
132         Tmap1.dest_row_data = GR_SCREEN_PTR(ubyte,lx,y);
133         Tmap1.loop_count = rx - lx;
134         Tmap1.pixptr = (unsigned char *)tmap_bitmap->data;
135         Tmap1.bp = tmap_bitmap;
136         Tmap1.src_offset = tmap_bitmap->w;
137
138         Tmap1.fx_u = fl2f(p->u);
139         Tmap1.fx_v = fl2f(p->v);
140         Tmap1.fx_du_dx = fl2f(dp->u);
141         Tmap1.fx_dv_dx = fl2f(dp->v);
142         Tmap1.fx_u_right = fl2f(rp->u);
143         Tmap1.fx_v_right = fl2f(rp->v);
144
145         asm_tmap_scanline_lnt();
146 }
147
148 extern void asm_tmap_scanline_lnn();
149
150 void tmapscan_lnn8( int lx, int rx, int y, vertex *p, vertex *dp,  vertex * rp,uint flags )
151 {
152         Tmap1.dest_row_data = GR_SCREEN_PTR(ubyte,lx,y);
153         Tmap1.loop_count = rx - lx;
154         Tmap1.pixptr = (unsigned char *)tmap_bitmap->data;
155         Tmap1.bp = tmap_bitmap;
156         Tmap1.src_offset = tmap_bitmap->w;
157
158         Tmap1.fx_u = fl2f(p->u);
159         Tmap1.fx_v = fl2f(p->v);
160         Tmap1.fx_du_dx = fl2f(dp->u);
161         Tmap1.fx_dv_dx = fl2f(dp->v);
162         Tmap1.fx_u_right = fl2f(rp->u);
163         Tmap1.fx_v_right = fl2f(rp->v);
164
165         asm_tmap_scanline_lnn();
166 }
167
168
169 void tmapscan_lln8_tiled( int lx, int rx, int y, vertex *p, vertex *dp,  vertex * rp,uint flags )
170 {
171         Tmap1.dest_row_data = GR_SCREEN_PTR(ubyte,lx,y);
172         Tmap1.loop_count = rx - lx;
173         Tmap1.fx_u = fl2f(p->u);
174         Tmap1.fx_v = fl2f(p->v);
175         Tmap1.fx_l = fl2f(p->l*32.0); 
176         Tmap1.fx_du_dx = fl2f(dp->u);
177         Tmap1.fx_dv_dx = fl2f(dp->v);
178         Tmap1.fx_dl_dx = fl2f(dp->l*32.0);
179         Tmap1.fx_u_right = fl2f(rp->u);
180         Tmap1.fx_v_right = fl2f(rp->v);
181         Tmap1.pixptr = (unsigned char *)tmap_bitmap->data;
182         Tmap1.bp = tmap_bitmap;
183         Tmap1.src_offset = tmap_bitmap->w;
184
185         Tmap1.BitmapWidth = tmap_bitmap->w;
186         Tmap1.BitmapHeight = tmap_bitmap->h;
187
188
189 //      asm_tmap_scanline_lln_tiled();
190
191
192 }
193
194
195
196 void c_tmap_scanline_per_sub_new();
197
198 void tmapscan_pln8( int lx, int rx, int y, vertex *p, vertex *dp,  vertex * rp,uint flags )
199 {
200         Tmap1.dest_row_data = GR_SCREEN_PTR(ubyte,lx,y);
201         Tmap1.loop_count = rx - lx;
202         Tmap1.fx_l = fl2f(p->l*32.0); 
203         Tmap1.fx_dl_dx = fl2f(dp->l*32.0);
204
205    Tmap1.UOverZ = p->u;
206         Tmap1.VOverZ = p->v;
207         Tmap1.OneOverZ = p->sw;
208
209         Tmap1.dUOverZdX8 = dp->u*32.0f;
210         Tmap1.dVOverZdX8 = dp->v*32.0f;
211         Tmap1.dOneOverZdX8 = dp->sw*32.0f;
212
213         Tmap1.dUOverZdX = dp->u;
214         Tmap1.dVOverZdX = dp->v;
215         Tmap1.dOneOverZdX = dp->sw;
216
217    Tmap1.RightUOverZ = rp->u;
218         Tmap1.RightVOverZ = rp->v;
219         Tmap1.RightOneOverZ = rp->sw;
220
221         if ( Tmap1.fx_dl_dx < 0 )       {
222                 Tmap1.fx_dl_dx = -Tmap1.fx_dl_dx;
223                 Tmap1.fx_l = (67*F1_0)-Tmap1.fx_l;
224                 Tmap1.fx_l_right = (67*F1_0)-Tmap1.fx_l_right;
225 //              return;
226 //              Assert( Tmap1.fx_l > 31*F1_0 );
227 //              Assert( Tmap1.fx_l < 66*F1_0 );
228 //              Assert( Tmap1.fx_dl_dx >= 0 );
229 //              Assert( Tmap1.fx_dl_dx < 31*F1_0 );
230         }
231
232 //      return;
233
234
235         if (0) {
236                         ubyte *dest, c;
237                         int x;
238                         fix l, dldx;
239
240                         l = Tmap1.fx_l;
241                         dldx = Tmap1.fx_dl_dx;
242                         dest = Tmap1.dest_row_data;
243
244                         for (x=Tmap1.loop_count; x >= 0; x-- ) {
245                                 //*dest++ = gr_fade_table[ ((l>>8)&(0xff00)) + 35 ];
246                                 c = *dest;
247                                 *dest++ = c+1;
248                                 l += dldx;
249                         }
250                         return;
251         }
252
253
254         _asm {
255         
256         push    eax
257         push    ecx
258         push    edx
259         push    ebx
260         push    ebp
261         push    esi
262         push    edi
263
264
265         // put the FPU in 32 bit mode
266         // @todo move this out of here!
267
268         fstcw           Tmap1.OldFPUCW                                  // store copy of CW
269         mov             ax,Tmap1.OldFPUCW                               // get it in ax
270         and             eax, ~0x300L
271         mov             Tmap1.FPUCW,ax                                  // store it
272         fldcw           Tmap1.FPUCW                                             // load the FPU
273
274         mov             ecx, Tmap1.loop_count           // ecx = width
275         inc             ecx
276         mov             edi, Tmap1.dest_row_data        // edi = dest pointer
277
278         // edi = pointer to start pixel in dest dib
279         // ecx = spanwidth
280
281         mov             eax,ecx                                                 // eax and ecx = width
282         shr             ecx,5                                                           // ecx = width / subdivision length
283         and             eax,31                                                          // eax = width mod subdivision length
284         jnz             some_left_over                                  // any leftover?
285 //      jmp             Return
286         dec             ecx                                                             // no, so special case last span
287         mov             eax,32                                                          // it's 8 pixels long
288 some_left_over:
289         mov             Tmap1.Subdivisions,ecx          // store widths
290         mov             Tmap1.WidthModLength,eax
291     
292 //    mov     ebx,pLeft                   ; get left edge pointer
293 //    mov     edx,pGradients              ; get gradients pointer
294
295         // calculate ULeft and VLeft                    // FPU Stack (ZL = ZLeft)
296                                                                                                         // st0  st1  st2  st3  st4  st5  st6  st7
297         fld             Tmap1.VOverZ                                    // V/ZL 
298         fld             Tmap1.UOverZ                                    // U/ZL V/ZL 
299         fld             Tmap1.OneOverZ                                  // 1/ZL U/ZL V/ZL 
300         fld1                                                                                    // 1    1/ZL U/ZL V/ZL 
301         fdiv            st,st(1)                                                        // ZL   1/ZL U/ZL V/ZL 
302         fld             st                                                                      // ZL   ZL   1/ZL U/ZL V/ZL 
303         fmul            st,st(4)                                                        // VL   ZL   1/ZL U/ZL V/ZL 
304         fxch            st(1)                                                           // ZL   VL   1/ZL U/ZL V/ZL 
305         fmul            st,st(3)                                                        // UL   VL   1/ZL U/ZL V/ZL 
306
307         fstp            st(5)                                                           // VL   1/ZL U/ZL V/ZL UL
308         fstp            st(5)                                                           // 1/ZL U/ZL V/ZL UL   VL
309
310         // calculate right side OverZ terms  ; st0  st1  st2  st3  st4  st5  st6  st7
311
312         fadd            Tmap1.dOneOverZdX8                      // 1/ZR U/ZL V/ZL UL   VL
313         fxch            st(1)                                                           // U/ZL 1/ZR V/ZL UL   VL
314         fadd            Tmap1.dUOverZdX8                                // U/ZR 1/ZR V/ZL UL   VL
315         fxch            st(2)                                                           // V/ZL 1/ZR U/ZR UL   VL
316         fadd            Tmap1.dVOverZdX8                                // V/ZR 1/ZR U/ZR UL   VL
317
318         // calculate right side coords          // st0  st1  st2  st3  st4  st5  st6  st7
319
320         fld1                                                                                    // 1    V/ZR 1/ZR U/ZR UL   VL
321         // @todo overlap this guy
322         fdiv            st,st(2)                                                        // ZR   V/ZR 1/ZR U/ZR UL   VL
323         fld             st                                                                      // ZR   ZR   V/ZR 1/ZR U/ZR UL   VL
324         fmul            st,st(2)                                                        // VR   ZR   V/ZR 1/ZR U/ZR UL   VL
325         fxch            st(1)                                                           // ZR   VR   V/ZR 1/ZR U/ZR UL   VL
326         fmul            st,st(4)                                                        // UR   VR   V/ZR 1/ZR U/ZR UL   VL
327
328         cmp             ecx,0                                                   // check for any full spans
329         jle      HandleLeftoverPixels
330     
331 SpanLoop:
332
333         // at this point the FPU contains       // st0  st1  st2  st3  st4  st5  st6  st7
334                                                                                                         // UR   VR   V/ZR 1/ZR U/ZR UL   VL
335
336         // convert left side coords
337
338         fld     st(5)                       ; UL   UR   VR   V/ZR 1/ZR U/ZR UL   VL
339         fmul    Tmap1.FixedScale            ; UL16 UR   VR   V/ZR 1/ZR U/ZR UL   VL
340         fistp   Tmap1.UFixed                ; UR   VR   V/ZR 1/ZR U/ZR UL   VL
341
342         fld     st(6)                       ; VL   UR   VR   V/ZR 1/ZR U/ZR UL   VL
343         fmul    Tmap1.FixedScale            ; VL16 UR   VR   V/ZR 1/ZR U/ZR UL   VL
344         fistp   Tmap1.VFixed                ; UR   VR   V/ZR 1/ZR U/ZR UL   VL
345
346         // calculate deltas                  ; st0  st1  st2  st3  st4  st5  st6  st7
347
348         fsubr   st(5),st                    ; UR   VR   V/ZR 1/ZR U/ZR dU   VL
349         fxch    st(1)                       ; VR   UR   V/ZR 1/ZR U/ZR dU   VL
350         fsubr   st(6),st                    ; VR   UR   V/ZR 1/ZR U/ZR dU   dV
351         fxch    st(6)                       ; dV   UR   V/ZR 1/ZR U/ZR dU   VR
352
353         fmul    Tmap1.FixedScale8           ; dV8  UR   V/ZR 1/ZR U/ZR dU   VR
354         fistp   Tmap1.DeltaV                ; UR   V/ZR 1/ZR U/ZR dU   VR
355
356         fxch    st(4)                       ; dU   V/ZR 1/ZR U/ZR UR   VR
357         fmul    Tmap1.FixedScale8           ; dU8  V/ZR 1/ZR U/ZR UR   VR
358         fistp   Tmap1.DeltaU                ; V/ZR 1/ZR U/ZR UR   VR
359
360         // increment terms for next span     ; st0  st1  st2  st3  st4  st5  st6  st7
361         // Right terms become Left terms---->; V/ZL 1/ZL U/ZL UL   VL
362
363         fadd    Tmap1.dVOverZdX8            ; V/ZR 1/ZL U/ZL UL   VL
364         fxch    st(1)                       ; 1/ZL V/ZR U/ZL UL   VL
365         fadd    Tmap1.dOneOverZdX8          ; 1/ZR V/ZR U/ZL UL   VL
366         fxch    st(2)                       ; U/ZL V/ZR 1/ZR UL   VL
367         fadd    Tmap1.dUOverZdX8            ; U/ZR V/ZR 1/ZR UL   VL
368         fxch    st(2)                       ; 1/ZR V/ZR U/ZR UL   VL
369         fxch    st(1)                       ; V/ZR 1/ZR U/ZR UL   VL
370
371
372     ; set up affine registers
373
374     ; setup delta values
375     
376     mov     eax,Tmap1.DeltaV                ; get v 16.16 step
377     mov     ebx,eax                     ; copy it
378     sar     eax,16                      ; get v int step
379     shl     ebx,16                      ; get v frac step
380     mov     Tmap1.DeltaVFrac,ebx            ; store it
381     imul    eax,Tmap1.src_offset      ; calculate texture step for v int step
382
383     mov     ebx,Tmap1.DeltaU                ; get u 16.16 step
384     mov     ecx,ebx                     ; copy it
385     sar     ebx,16                      ; get u int step
386     shl     ecx,16                      ; get u frac step
387     mov     Tmap1.DeltaUFrac,ecx            ; store it
388     add     eax,ebx                     ; calculate uint + vint step
389     mov     Tmap1.UVintVfracStepVNoCarry,eax; save whole step in non-v-carry slot
390     add     eax,Tmap1.src_offset      ; calculate whole step + v carry
391     mov     Tmap1.UVintVfracStepVCarry,eax  ; save in v-carry slot
392
393 ; setup initial coordinates
394     mov     esi,Tmap1.UFixed                ; get u 16.16 fixedpoint coordinate
395    
396     mov     ebx,esi                     ; copy it
397     sar     esi,16                      ; get integer part
398     shl     ebx,16                      ; get fractional part
399     
400     mov     ecx,Tmap1.VFixed                ; get v 16.16 fixedpoint coordinate
401    
402     mov     edx,ecx                     ; copy it
403     sar     edx,16                      ; get integer part
404     shl     ecx,16                      ; get fractional part
405     imul    edx,Tmap1.src_offset      ; calc texture scanline address
406     add     esi,edx                     ; calc texture offset
407     add     esi,Tmap1.pixptr          ; calc address
408
409         mov     edx,Tmap1.DeltaUFrac            ; get register copy
410
411         mov     eax, Tmap1.fx_l
412         shr     eax, 8
413         mov     bx, ax
414
415         mov     ebp, Tmap1.fx_dl_dx
416         shl     ebp, 5  //*32
417         add     Tmap1.fx_l, ebp
418
419         mov     ebp, Tmap1.fx_l
420         shr     ebp, 8
421         sub     bp, ax
422         shr     bp, 5
423
424         mov     dx, bp
425
426
427         ; calculate right side coords       ; st0  st1  st2  st3  st4  st5  st6  st7
428
429         fld1                                ; 1    V/ZR 1/ZR U/ZR UL   VL
430         fdiv    st,st(2)                    ; ZR   V/ZR 1/ZR U/ZR UL   VL
431
432
433     // 8 pixel span code
434     // edi = dest dib bits at current pixel
435     // esi = texture pointer at current u,v
436     // eax = scratch
437     // ebx = u fraction 0.32
438     // ecx = v fraction 0.32
439     // edx = u frac step
440     // ebp = v carry scratch
441
442     mov     al,[edi]                    // preread the destination cache line
443
444
445     mov     al,[esi]                    // get texture pixel 0
446     mov         ah, bh
447     mov         al, gr_fade_table[eax]
448
449     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
450     sbb     ebp,ebp                     // get -1 if carry
451     add     ebx,edx                     // increment u fraction
452
453     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
454     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
455
456     sbb     ebp,ebp                     // get -1 if carry
457 //      mov al, 0       // Uncomment this line to show divisions
458     mov     [edi+0],al                  // store pixel 0
459
460     add     ebx,edx                     // increment u fraction
461     mov     al,[esi]                    // get texture pixel 1
462     mov         ah, bh
463     mov         al, gr_fade_table[eax]
464
465     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
466     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
467
468     sbb     ebp,ebp                     // get -1 if carry
469     mov     [edi+1],al                  // store pixel 1
470
471     add     ebx,edx                     // increment u fraction
472     mov     al,[esi]                    // get texture pixel 2
473     mov         ah, bh
474     mov         al, gr_fade_table[eax]
475
476     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
477     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
478
479     sbb     ebp,ebp                     // get -1 if carry
480     mov     [edi+2],al                  // store pixel 2
481
482     add     ebx,edx                     // increment u fraction
483     mov     al,[esi]                    // get texture pixel 3
484     mov         ah, bh
485     mov         al, gr_fade_table[eax]
486
487     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
488     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
489
490     sbb     ebp,ebp                     // get -1 if carry
491     mov     [edi+3],al                  // store pixel 3
492
493     add     ebx,edx                     // increment u fraction
494     mov     al,[esi]                    // get texture pixel 4
495     mov         ah, bh
496     mov         al, gr_fade_table[eax]
497     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
498     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
499
500     sbb     ebp,ebp                     // get -1 if carry
501     mov     [edi+4],al                  // store pixel 3
502
503     add     ebx,edx                     // increment u fraction
504     mov     al,[esi]                    // get texture pixel 4
505     mov         ah, bh
506     mov         al, gr_fade_table[eax]
507     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
508     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
509
510     sbb     ebp,ebp                     // get -1 if carry
511     mov     [edi+5],al                  // store pixel 3
512
513     add     ebx,edx                     // increment u fraction
514     mov     al,[esi]                    // get texture pixel 4
515     mov         ah, bh
516     mov         al, gr_fade_table[eax]
517     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
518     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
519
520     sbb     ebp,ebp                     // get -1 if carry
521     mov     [edi+6],al                  // store pixel 3
522
523     add     ebx,edx                     // increment u fraction
524     mov     al,[esi]                    // get texture pixel 4
525     mov         ah, bh
526     mov         al, gr_fade_table[eax]
527     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
528     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
529
530     sbb     ebp,ebp                     // get -1 if carry
531     mov     [edi+7],al                  // store pixel 3
532
533     add     ebx,edx                     // increment u fraction
534     mov     al,[esi]                    // get texture pixel 4
535     mov         ah, bh
536     mov         al, gr_fade_table[eax]
537     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
538     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
539
540     sbb     ebp,ebp                     // get -1 if carry
541     mov     [edi+8],al                  // store pixel 3
542
543     add     ebx,edx                     // increment u fraction
544     mov     al,[esi]                    // get texture pixel 4
545     mov         ah, bh
546     mov         al, gr_fade_table[eax]
547     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
548     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
549
550     sbb     ebp,ebp                     // get -1 if carry
551     mov     [edi+9],al                  // store pixel 3
552
553     add     ebx,edx                     // increment u fraction
554     mov     al,[esi]                    // get texture pixel 4
555     mov         ah, bh
556     mov         al, gr_fade_table[eax]
557     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
558     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
559
560     sbb     ebp,ebp                     // get -1 if carry
561     mov     [edi+10],al                  // store pixel 3
562
563     add     ebx,edx                     // increment u fraction
564     mov     al,[esi]                    // get texture pixel 4
565     mov         ah, bh
566     mov         al, gr_fade_table[eax]
567
568
569     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
570     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
571
572     sbb     ebp,ebp                     // get -1 if carry
573     mov     [edi+11],al                  // store pixel 3
574
575     add     ebx,edx                     // increment u fraction
576     mov     al,[esi]                    // get texture pixel 4
577     mov         ah, bh
578     mov         al, gr_fade_table[eax]
579
580
581     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
582     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
583
584     sbb     ebp,ebp                     // get -1 if carry
585     mov     [edi+12],al                  // store pixel 3
586
587     add     ebx,edx                     // increment u fraction
588     mov     al,[esi]                    // get texture pixel 4
589     mov         ah, bh
590     mov         al, gr_fade_table[eax]
591
592
593     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
594     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
595
596     sbb     ebp,ebp                     // get -1 if carry
597     mov     [edi+13],al                  // store pixel 3
598
599     add     ebx,edx                     // increment u fraction
600     mov     al,[esi]                    // get texture pixel 4
601     mov         ah, bh
602     mov         al, gr_fade_table[eax]
603
604
605     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
606     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
607
608     sbb     ebp,ebp                     // get -1 if carry
609     mov     [edi+14],al                  // store pixel 3
610
611     add     ebx,edx                     // increment u fraction
612     mov     al,[esi]                    // get texture pixel 4
613     mov         ah, bh
614     mov         al, gr_fade_table[eax]
615
616
617     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
618     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
619
620     sbb     ebp,ebp                     // get -1 if carry
621     mov     [edi+15],al                  // store pixel 3
622
623     add     ebx,edx                     // increment u fraction
624     mov     al,[esi]                    // get texture pixel 4
625     mov         ah, bh
626     mov         al, gr_fade_table[eax]
627
628
629     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
630     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
631
632     sbb     ebp,ebp                     // get -1 if carry
633     mov     [edi+16],al                  // store pixel 3
634
635     add     ebx,edx                     // increment u fraction
636     mov     al,[esi]                    // get texture pixel 4
637     mov         ah, bh
638     mov         al, gr_fade_table[eax]
639
640
641     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
642     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
643
644     sbb     ebp,ebp                     // get -1 if carry
645     mov     [edi+17],al                  // store pixel 3
646
647     add     ebx,edx                     // increment u fraction
648     mov     al,[esi]                    // get texture pixel 4
649     mov         ah, bh
650     mov         al, gr_fade_table[eax]
651
652
653     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
654     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
655
656     sbb     ebp,ebp                     // get -1 if carry
657     mov     [edi+18],al                  // store pixel 3
658
659     add     ebx,edx                     // increment u fraction
660     mov     al,[esi]                    // get texture pixel 4
661     mov         ah, bh
662     mov         al, gr_fade_table[eax]
663
664
665     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
666     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
667
668     sbb     ebp,ebp                     // get -1 if carry
669     mov     [edi+19],al                  // store pixel 3
670
671     add     ebx,edx                     // increment u fraction
672     mov     al,[esi]                    // get texture pixel 4
673     mov         ah, bh
674     mov         al, gr_fade_table[eax]
675
676
677     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
678     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
679
680     sbb     ebp,ebp                     // get -1 if carry
681     mov     [edi+20],al                  // store pixel 3
682
683     add     ebx,edx                     // increment u fraction
684     mov     al,[esi]                    // get texture pixel 4
685     mov         ah, bh
686     mov         al, gr_fade_table[eax]
687
688
689     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
690     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
691
692     sbb     ebp,ebp                     // get -1 if carry
693     mov     [edi+21],al                  // store pixel 3
694
695     add     ebx,edx                     // increment u fraction
696     mov     al,[esi]                    // get texture pixel 4
697     mov         ah, bh
698     mov         al, gr_fade_table[eax]
699
700
701     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
702     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
703
704     sbb     ebp,ebp                     // get -1 if carry
705     mov     [edi+22],al                  // store pixel 3
706
707     add     ebx,edx                     // increment u fraction
708     mov     al,[esi]                    // get texture pixel 4
709     mov         ah, bh
710     mov         al, gr_fade_table[eax]
711
712
713     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
714     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
715
716     sbb     ebp,ebp                     // get -1 if carry
717     mov     [edi+23],al                  // store pixel 3
718
719     add     ebx,edx                     // increment u fraction
720     mov     al,[esi]                    // get texture pixel 4
721     mov         ah, bh
722     mov         al, gr_fade_table[eax]
723
724
725     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
726     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
727
728     sbb     ebp,ebp                     // get -1 if carry
729     mov     [edi+24],al                  // store pixel 3
730
731     add     ebx,edx                     // increment u fraction
732     mov     al,[esi]                    // get texture pixel 4
733     mov         ah, bh
734     mov         al, gr_fade_table[eax]
735
736
737     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
738     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
739
740     sbb     ebp,ebp                     // get -1 if carry
741     mov     [edi+25],al                  // store pixel 3
742
743     add     ebx,edx                     // increment u fraction
744     mov     al,[esi]                    // get texture pixel 4
745     mov         ah, bh
746     mov         al, gr_fade_table[eax]
747
748
749     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
750     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
751
752
753
754     sbb     ebp,ebp                     // get -1 if carry
755     mov     [edi+26],al                  // store pixel 3
756
757     add     ebx,edx                     // increment u fraction
758     mov     al,[esi]                    // get texture pixel 4
759     mov         ah, bh
760     mov         al, gr_fade_table[eax]
761
762
763     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
764     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
765
766     sbb     ebp,ebp                     // get -1 if carry
767     mov     [edi+27],al                  // store pixel 3
768
769     add     ebx,edx                     // increment u fraction
770     mov     al,[esi]                    // get texture pixel 4
771     mov         ah, bh
772     mov         al, gr_fade_table[eax]
773
774     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
775     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
776
777     sbb     ebp,ebp                     // get -1 if carry
778     mov     [edi+28],al                  // store pixel 4
779
780     add     ebx,edx                     // increment u fraction
781     mov     al,[esi]                    // get texture pixel 5
782     mov         ah, bh
783     mov         al, gr_fade_table[eax]
784
785     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
786     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
787
788     sbb     ebp,ebp                     // get -1 if carry
789     mov     [edi+29],al                  // store pixel 5
790
791     add     ebx,edx                     // increment u fraction
792     mov     al,[esi]                    // get texture pixel 6
793     mov         ah, bh
794     mov         al, gr_fade_table[eax]
795
796     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
797     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
798
799     sbb     ebp,ebp                     // get -1 if carry
800     mov     [edi+30],al                  // store pixel 6
801
802     add     ebx,edx                     // increment u fraction
803
804     mov     al,[esi]                    // get texture pixel 7
805     mov         ah, bh
806     mov         al, gr_fade_table[eax]
807
808     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
809
810     mov     [edi+31],al                 // store pixel 7
811
812
813     
814     ; ************** Okay to Access Stack Frame ****************
815     ; ************** Okay to Access Stack Frame ****************
816     ; ************** Okay to Access Stack Frame ****************
817
818
819     ; the fdiv is done, finish right    ; st0  st1  st2  st3  st4  st5  st6  st7
820                                         ; ZR   V/ZR 1/ZR U/ZR UL   VL
821
822     fld     st                          ; ZR   ZR   V/ZR 1/ZR U/ZR UL   VL
823     fmul    st,st(2)                    ; VR   ZR   V/ZR 1/ZR U/ZR UL   VL
824     fxch    st(1)                       ; ZR   VR   V/ZR 1/ZR U/ZR UL   VL
825     fmul    st,st(4)                    ; UR   VR   V/ZR 1/ZR U/ZR UL   VL
826
827     add     edi,32                       ; increment to next span
828     dec     Tmap1.Subdivisions              ; decrement span count
829     jnz     SpanLoop                    ; loop back
830
831         // save new lighting values
832 //      xor     eax, eax
833 //      mov     ax, bx
834 //      mov     Tmap1.fx_l, eax
835
836 //      xor     eax, eax
837 //      mov     ax, dx
838 //      mov     Tmap1.fx_dl_dx, eax
839
840 HandleLeftoverPixels:
841 //      jmp     FPUReturn
842
843     mov     esi,Tmap1.pixptr          ; load texture pointer
844
845     ; edi = dest dib bits
846     ; esi = current texture dib bits
847     ; at this point the FPU contains    ; st0  st1  st2  st3  st4  st5  st6  st7
848     ; inv. means invalid numbers        ; inv. inv. inv. inv. inv. UL   VL
849
850     cmp     Tmap1.WidthModLength,0          ; are there remaining pixels to draw?
851     jz      FPUReturn                   ; nope, pop the FPU and bail
852
853     ; convert left side coords          ; st0  st1  st2  st3  st4  st5  st6  st7
854
855     fld     st(5)                       ; UL   inv. inv. inv. inv. inv. UL   VL
856     fmul    Tmap1.FixedScale                ; UL16 inv. inv. inv. inv. inv. UL   VL
857     fistp   Tmap1.UFixed                    ; inv. inv. inv. inv. inv. UL   VL
858
859     fld     st(6)                       ; VL   inv. inv. inv. inv. inv. UL   VL
860     fmul    Tmap1.FixedScale                // VL16 inv. inv. inv. inv. inv. UL   VL
861     fistp   Tmap1.VFixed                    ; inv. inv. inv. inv. inv. UL   VL
862
863     dec     Tmap1.WidthModLength            ; calc how many steps to take
864     jz      OnePixelSpan                ; just one, don't do deltas
865
866     ; calculate right edge coordinates  ; st0  st1  st2  st3  st4  st5  st6  st7
867     ; r -> R+1
868
869     ; @todo rearrange things so we don't need these two instructions
870     fstp    Tmap1.FloatTemp                 ; inv. inv. inv. inv. UL   VL
871     fstp    Tmap1.FloatTemp                 ; inv. inv. inv. UL   VL
872
873     fld     Tmap1.RightVOverZ           ; V/Zr inv. inv. inv. UL   VL
874     fsub    Tmap1.dVOverZdX             ; V/ZR inv. inv. inv. UL   VL
875     fld     Tmap1.RightUOverZ           ; U/Zr V/ZR inv. inv. inv. UL   VL
876     fsub    Tmap1.dUOverZdX             ; U/ZR V/ZR inv. inv. inv. UL   VL
877     fld     Tmap1.RightOneOverZ              ; 1/Zr U/ZR V/ZR inv. inv. inv. UL   VL
878     fsub    Tmap1.dOneOverZdX           ; 1/ZR U/ZR V/ZR inv. inv. inv. UL   VL
879
880     fdivr   Tmap1.One                       ; ZR   U/ZR V/ZR inv. inv. inv. UL   VL
881
882     fmul    st(1),st                    ; ZR   UR   V/ZR inv. inv. inv. UL   VL
883     fmulp   st(2),st                    ; UR   VR   inv. inv. inv. UL   VL
884
885     ; calculate deltas                  ; st0  st1  st2  st3  st4  st5  st6  st7
886
887     fsubr   st(5),st                    ; UR   VR   inv. inv. inv. dU   VL
888     fxch    st(1)                       ; VR   UR   inv. inv. inv. dU   VL
889     fsubr   st(6),st                    ; VR   UR   inv. inv. inv. dU   dV
890     fxch    st(6)                       ; dV   UR   inv. inv. inv. dU   VR
891
892     fidiv   Tmap1.WidthModLength            ; dv   UR   inv. inv. inv. dU   VR
893     fmul    Tmap1.FixedScale                ; dv16 UR   inv. inv. inv. dU   VR
894     fistp   Tmap1.DeltaV                    ; UR   inv. inv. inv. dU   VR
895
896     fxch    st(4)                       ; dU   inv. inv. inv. UR   VR
897     fidiv   Tmap1.WidthModLength            ; du   inv. inv. inv. UR   VR
898     fmul    Tmap1.FixedScale                ; du16 inv. inv. inv. UR   VR
899     fistp   Tmap1.DeltaU                    ; inv. inv. inv. UR   VR
900
901     ; @todo gross!  these are to line up with the other loop
902     fld     st(1)                       ; inv. inv. inv. inv. UR   VR
903     fld     st(2)                       ; inv. inv. inv. inv. inv. UR   VR
904
905 //jmp OldWay
906
907
908         ; setup delta values
909         mov     eax, Tmap1.DeltaV       // get v 16.16 step
910         mov     ebx, eax                                                // copy it
911         sar     eax, 16                                         // get v int step
912         shl     ebx, 16                                         // get v frac step
913         mov     Tmap1.DeltaVFrac, ebx   // store it
914         imul    eax, Tmap1.src_offset   // calc texture step for v int step
915         
916         mov     ebx, Tmap1.DeltaU                       // get u 16.16 step
917         mov     ecx, ebx                                                // copy it
918         sar     ebx, 16                                         // get the u int step
919         shl     ecx, 16                                         // get the u frac step
920         mov     Tmap1.DeltaUFrac, ecx                   // store it
921         add     eax, ebx                                                // calc uint + vint step
922         mov     Tmap1.UVintVfracStepVNoCarry, eax       // save whole step in non-v-carry slot
923         add     eax, Tmap1.src_offset                           // calc whole step + v carry
924         mov     Tmap1.UVintVfracStepVCarry, eax // save in v-carry slot
925
926
927
928 OnePixelSpan:
929
930 /*
931 ; check coordinate ranges
932         mov     eax, Tmap1.UFixed
933         cmp     eax, Tmap1.MinUFixed
934         jge     UNotTooSmall_2
935         mov     eax, Tmap1.MinUFixed
936         mov     Tmap1.UFixed, eax
937         jmp     CheckV_2
938 UNotTooSmall_2: 
939         cmp     eax, Tmap1.MaxUFixed
940         jle     CheckV_2
941         mov     eax, Tmap1.MaxUFixed
942         mov     Tmap1.UFixed, eax
943 CheckV_2:
944         mov     eax, Tmap1.VFixed
945         cmp     eax, Tmap1.MinVFixed
946         jge     VNotTooSmall_2
947         mov     eax, Tmap1.MinVFixed
948         mov     Tmap1.VFixed, eax
949         jmp     DoneCheck_2
950 VNotTooSmall_2: 
951         cmp     eax, Tmap1.MaxVFixed
952         jle     DoneCheck_2
953         mov     eax, Tmap1.MaxVFixed
954         mov     Tmap1.VFixed, eax
955 DoneCheck_2:
956 */
957
958
959
960
961         ; setup initial coordinates
962         mov     esi, Tmap1.UFixed                       // get u 16.16
963         mov     ebx, esi                                                // copy it
964         sar     esi, 16                                         // get integer part
965         shl     ebx, 16                                         // get fractional part
966
967         mov     ecx, Tmap1.VFixed                       // get v 16.16 
968         mov     edx, ecx                                                // copy it
969         sar     edx, 16                                         // get integer part
970         shl     ecx, 16                                         // get fractional part
971         imul    edx, Tmap1.src_offset           // calc texture scanline address
972         add     esi, edx                                                        // calc texture offset
973         add     esi, Tmap1.pixptr                       // calc address
974         
975         ; set edi = address of first pixel to modify
976 ;       mov     edi, Tmap1.dest_row_data
977
978
979
980
981         mov     eax, Tmap1.fx_l
982         shr     eax, 8
983         mov     bx, ax
984
985         mov     edx, Tmap1.DeltaUFrac
986
987         cmp     Tmap1.WidthModLength, 1
988         jle     NoDeltaLight
989
990         push    ebx
991         
992         mov     ebx, Tmap1.fx_l_right
993         shr     ebx, 8
994         
995         sub     ebx, eax
996         mov     eax, ebx
997         
998 #if 0
999         // slow but maybe better
1000         push    edx
1001         cdq
1002         mov     ebx, Tmap1.WidthModLength 
1003         dec     ebx
1004         idiv    ebx
1005         pop     edx
1006 #else
1007         mov     eax, Tmap1.fx_dl_dx
1008         shr     eax, 8
1009 #endif
1010
1011         mov     dx, ax
1012
1013         pop     ebx
1014
1015 NoDeltaLight:
1016
1017         inc     Tmap1.WidthModLength
1018         mov     eax,Tmap1.WidthModLength
1019         shr     eax, 1
1020         jz              one_more_pix
1021         pushf
1022         mov     Tmap1.WidthModLength, eax
1023
1024         xor     eax, eax
1025
1026     mov     al,[edi]                    // preread the destination cache line
1027
1028 NextPixel:
1029     mov     al,[esi]                    // get texture pixel 0
1030     mov         ah, bh
1031     mov         al, gr_fade_table[eax]
1032
1033     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
1034     sbb     ebp,ebp                     // get -1 if carry
1035     add     ebx,edx                     // increment u fraction
1036     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
1037     mov     [edi+0],al                  // store pixel 0
1038
1039     add     ecx,Tmap1.DeltaVFrac        // increment v fraction
1040     sbb     ebp,ebp                     // get -1 if carry
1041     add     ebx,edx                     // increment u fraction
1042     mov     al,[esi]                    // get texture pixel 1
1043     mov         ah, bh
1044     mov         al, gr_fade_table[eax]
1045
1046     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
1047     mov     [edi+1],al                  // store pixel 1
1048
1049         add     edi, 2
1050         dec     Tmap1.WidthModLength
1051         jg              NextPixel
1052
1053         popf
1054         jnc     FPUReturn
1055
1056 one_more_pix:   
1057
1058     mov     al,[esi]                    // get texture pixel 2
1059     mov         ah, bh
1060     mov         al, gr_fade_table[eax]
1061     mov     [edi],al                  // store pixel 2
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075 /* 
1076 OldWay:         // This is 6% slower than above
1077
1078     mov     ebx,Tmap1.UFixed                ; get starting coordinates
1079     mov     ecx,Tmap1.VFixed                ; for span
1080  
1081     ; leftover pixels loop
1082     ; edi = dest dib bits
1083     ; esi = texture dib bits
1084
1085     ; ebx = u 16.16
1086     ; ecx = v 16.16
1087
1088
1089     mov     eax,ecx                     ; copy v
1090     sar     eax,16                      ; int(v)
1091     imul    eax,Tmap1.src_offset      ; scan offset
1092     mov     edx,ebx                     ; copy u
1093     sar     edx,16                      ; int(u)
1094     add     eax,edx                     ; texture offset
1095     mov     al,[esi+eax]                ; get source pixel
1096 mov al, 0
1097     mov     [edi],al                    ; store it
1098     inc     edi
1099     add     ebx,Tmap1.DeltaU                  ; increment u coordinate
1100     add     ecx,Tmap1.DeltaV                  ; increment v coordinate
1101
1102     dec     Tmap1.WidthModLength            ; decrement loop count
1103     jl     FPUReturn                ; finish up
1104          
1105
1106 LeftoverLoop:
1107     mov     eax,ecx                     ; copy v
1108     sar     eax,16                      ; int(v)
1109     imul    eax,Tmap1.src_offset      ; scan offset
1110     mov     edx,ebx                     ; copy u
1111     sar     edx,16                      ; int(u)
1112     add     eax,edx                     ; texture offset
1113     mov     al,[esi+eax]                ; get source pixel
1114     mov     [edi],al                    ; store it
1115     inc     edi
1116     add     ebx,Tmap1.DeltaU                  ; increment u coordinate
1117     add     ecx,Tmap1.DeltaV                  ; increment v coordinate
1118
1119     dec     Tmap1.WidthModLength            ; decrement loop count
1120     jge     LeftoverLoop                ; finish up
1121 */
1122
1123 FPUReturn:
1124
1125     ; busy FPU registers:               ; st0  st1  st2  st3  st4  st5  st6  st7
1126                                         ; xxx  xxx  xxx  xxx  xxx  xxx  xxx
1127     ffree   st(0)
1128     ffree   st(1)
1129     ffree   st(2)
1130     ffree   st(3)
1131     ffree   st(4)
1132     ffree   st(5)
1133     ffree   st(6)
1134
1135     fldcw   Tmap1.OldFPUCW                  // restore the FPU
1136
1137         pop     edi
1138         pop     esi
1139         pop     ebp
1140         pop     ebx
1141         pop     edx
1142         pop     ecx
1143         pop     eax
1144         }
1145
1146
1147 }
1148
1149
1150 void tmapscan_lln8_old( int lx, int rx, int y, vertex *p, vertex *dp,  vertex * rp,uint flags )
1151 {
1152         _fx_srcptr = (uint)tmap_bitmap->data;
1153         _fx_destptr = (uint)GR_SCREEN_PTR(ubyte,lx,y);
1154         _loop_count = rx - lx;
1155         _fx_u = fl2f(p->u*64.0f);
1156         _fx_v = fl2f(p->v*64.0f);
1157         _fx_l = fl2f(p->l*32.0+1.0);
1158         _fx_du = fl2f(dp->u*64.0f);
1159         _fx_dv = fl2f(dp->v*64.0f);
1160         _fx_dl = fl2f(dp->l*32.0);
1161         light_table = (uint)&gr_fade_table[0];
1162
1163         _asm {
1164         push    eax
1165         push    ecx
1166         push    edx
1167         push    ebx
1168         push    ebp
1169         push    esi
1170         push    edi
1171         
1172         ; set edi = address of first pixel to modify
1173         mov     edi, _fx_destptr
1174
1175
1176         mov     eax, _fx_v
1177         shr     eax, 6
1178         mov     edx, _fx_u
1179         shl     edx, 10
1180         mov     dx, ax          ; EDX=U:V in 6.10 format
1181
1182         mov     eax, _fx_dv
1183         shr     eax, 6
1184         mov     esi, _fx_du
1185         shl     esi, 10
1186         mov     si, ax          ; ESI=DU:DV in 6.10 format
1187
1188         mov     ebx, _fx_l
1189         sar     ebx, 8
1190         mov     ebp, _fx_dl
1191         sar     ebp, 8
1192
1193         mov     ecx, _fx_srcptr
1194
1195         mov     eax, _loop_count
1196         inc     eax
1197         mov     _loop_count, eax
1198
1199         shr     eax, 3
1200         je              DoLeftOverPixels
1201
1202         mov     num_big_steps, eax
1203         and     _loop_count, 7
1204
1205 NextPixelBlock:
1206                 ; pixel 0
1207                 mov     eax, edx        
1208                 shr     ax, 10
1209                 rol     eax, 6
1210                 and     eax, 0ffffh
1211                 add     edx, esi
1212                 mov     al, [ecx+eax]                   
1213                 mov     ah, bh          
1214                 add     ebx, ebp
1215                 mov     al, gr_fade_table[eax]
1216                 mov     [edi+0], al
1217
1218                 ; pixel 1
1219                 mov     eax, edx        
1220                 shr     ax, 10
1221                 rol     eax, 6
1222                 and     eax, 0ffffh
1223                 add     edx, esi
1224                 mov     al, [ecx+eax]                   
1225                 mov     ah, bh          
1226                 add     ebx, ebp
1227                 mov     al, gr_fade_table[eax]
1228                 mov     [edi+1], al
1229
1230                 ; pixel 2
1231                 mov     eax, edx        
1232                 shr     ax, 10
1233                 rol     eax, 6
1234                 and     eax, 0ffffh
1235                 add     edx, esi
1236                 mov     al, [ecx+eax]                   
1237                 mov     ah, bh          
1238                 add     ebx, ebp
1239                 mov     al, gr_fade_table[eax]
1240                 mov     [edi+2], al
1241
1242                 ; pixel 3
1243                 mov     eax, edx        
1244                 shr     ax, 10
1245                 rol     eax, 6
1246                 and     eax, 0ffffh
1247                 add     edx, esi
1248                 mov     al, [ecx+eax]                   
1249                 mov     ah, bh          
1250                 add     ebx, ebp
1251                 mov     al, gr_fade_table[eax]
1252                 mov     [edi+3], al
1253
1254                 ; pixel 4
1255                 mov     eax, edx        
1256                 shr     ax, 10
1257                 rol     eax, 6
1258                 and     eax, 0ffffh
1259                 add     edx, esi
1260                 mov     al, [ecx+eax]                   
1261                 mov     ah, bh          
1262                 add     ebx, ebp
1263                 mov     al, gr_fade_table[eax]
1264                 mov     [edi+4], al
1265
1266                 ; pixel 5
1267                 mov     eax, edx        
1268                 shr     ax, 10
1269                 rol     eax, 6
1270                 and     eax, 0ffffh
1271                 add     edx, esi
1272                 mov     al, [ecx+eax]                   
1273                 mov     ah, bh          
1274                 add     ebx, ebp
1275                 mov     al, gr_fade_table[eax]
1276                 mov     [edi+5], al
1277
1278                 ; pixel 6
1279                 mov     eax, edx        
1280                 shr     ax, 10
1281                 rol     eax, 6
1282                 and     eax, 0ffffh
1283                 add     edx, esi
1284                 mov     al, [ecx+eax]                   
1285                 mov     ah, bh          
1286                 add     ebx, ebp
1287                 mov     al, gr_fade_table[eax]
1288                 mov     [edi+6], al
1289
1290                 ; pixel 7
1291                 mov     eax, edx        
1292                 shr     ax, 10
1293                 rol     eax, 6
1294                 and     eax, 0ffffh
1295                 add     edx, esi
1296                 mov     al, [ecx+eax]                   
1297                 mov     ah, bh          
1298                 add     ebx, ebp
1299                 mov     al, gr_fade_table[eax]
1300                 mov     [edi+7], al
1301
1302         add     edi, 8
1303         dec     num_big_steps
1304         jne     NextPixelBlock
1305         
1306
1307 DoLeftOverPixels:
1308         mov     eax,_loop_count
1309         test    eax, -1
1310         jz      _none_to_do
1311         shr     eax, 1
1312         je      one_more_pix
1313         mov     _loop_count, eax
1314         pushf
1315
1316
1317 NextPixel:
1318                 mov     eax, edx        
1319                 shr     ax, 10
1320                 rol     eax, 6
1321                 and     eax, 0ffffh
1322                 add     edx, esi
1323                 mov     al, [ecx+eax]                   
1324                 mov     ah, bh          
1325                 add     ebx, ebp
1326                 mov     al, gr_fade_table[eax]
1327                 mov     [edi+0], al
1328
1329                 mov     eax, edx        
1330                 shr     ax, 10
1331                 rol     eax, 6
1332                 and     eax, 0ffffh
1333                 add     edx, esi
1334                 mov     al, [ecx+eax]                   
1335                 mov     ah, bh          
1336                 add     ebx, ebp
1337                 mov     al, gr_fade_table[eax]
1338                 mov     [edi+1], al
1339
1340
1341         add     edi, 2
1342         dec     _loop_count
1343         jne     NextPixel
1344
1345         popf
1346         jnc     _none_to_do
1347
1348 one_more_pix:   
1349         mov     eax, edx        
1350         shr     ax, 10
1351         rol     eax, 6
1352         and     eax, 0ffffh
1353         mov     al, [ecx+eax]                   
1354         mov     ah, bh          
1355         mov     al, gr_fade_table[eax]
1356         mov     [edi], al
1357
1358 _none_to_do:    
1359         pop     edi
1360         pop     esi
1361         pop     ebp
1362         pop     ebx
1363         pop     edx
1364         pop     ecx
1365         pop     eax
1366         }
1367         
1368
1369 }
1370
1371
1372 void tmapscan_flat16( int lx, int rx, int y, vertex *p, vertex *dp,  vertex * rp,uint flags )
1373 {
1374         int i;
1375         ushort *pDestBits;
1376
1377         pDestBits = GR_SCREEN_PTR(ushort,lx,y);
1378         
1379         for (i=0; i<(rx-lx+1); i++ )
1380                 *pDestBits++ = gr_screen.current_color.raw16;
1381 }
1382
1383 float tmap_max_z = 0.0f;
1384
1385 void tmapscan_lln8_z( int lx, int rx, int y, vertex *p, vertex *dp,  vertex * rp,uint flags )
1386 {
1387         int count;
1388         ubyte *pDestBits, tmp;
1389         float u, dudx, v, dvdx, l, dldx;
1390         float z, dzdx;
1391
1392         pDestBits = GR_SCREEN_PTR(ubyte,lx,y);
1393
1394         ubyte * cdata = (ubyte *)tmap_bitmap->data;
1395
1396         u = p->u;
1397         v = p->v;
1398         l = p->l*32.0f;
1399         z = p->nz;
1400         dudx = dp->u;
1401         dvdx = dp->v;
1402         dldx = dp->l*32.0f;
1403         dzdx = dp->nz;
1404
1405         for ( count = rx - lx + 1 ; count > 0; count-- )        {
1406                 if ( z < tmap_max_z )   {
1407                         tmp = cdata[fl2i(v)*tmap_bitmap->w+fl2i(u)];
1408                         *pDestBits = gr_fade_table[ fl2i(l)*256+tmp ];
1409                 }
1410                 pDestBits++;
1411                 u += dudx;
1412                 v += dvdx;
1413                 l += dldx;
1414                 z += dzdx;
1415         }
1416 }
1417
1418
1419 void tmapscan_generic8( int lx, int rx, int y, vertex *p, vertex *dp,  vertex * rp,uint flags )
1420 {
1421         int count;
1422         ubyte *pDestBits, tmp;
1423         int u, dudx, v, dvdx, w, dwdx, l, dldx;
1424
1425         pDestBits = GR_SCREEN_PTR(ubyte,lx,y);
1426
1427         if ( Tmap1.flags & TMAP_FLAG_TEXTURED ) {
1428                 ubyte * cdata = (ubyte *)tmap_bitmap->data;
1429                 if ( flags & TMAP_FLAG_RAMP ) {
1430                         if ( Tmap1.flags & TMAP_FLAG_CORRECT )  {
1431                                 float fu, fv, fw, fdu, fdv, fdw;
1432
1433                                 tmapscan_pln8( lx, rx, y, p, dp,  rp,Tmap1.flags );
1434                                 return;
1435
1436
1437                                 fu = p->u;
1438                                 fv = p->v;
1439                                 fw = p->sw;
1440                                 l = fl2f(p->l*32.0f);
1441                                 
1442                                 fdu = dp->u;
1443                                 fdv = dp->v;
1444                                 fdw = dp->sw;
1445                                 dldx = fl2f(dp->l*32.0f);
1446                                                 
1447                                 for ( count = rx - lx + 1 ; count > 0; count-- )        {
1448                                         u = fl2i(fu/fw);
1449                                         v = fl2i(fv/fw);
1450                                         tmp = cdata[v*tmap_bitmap->w+u];
1451                                         *pDestBits++ = tmp; //gr_fade_table[ (l>>16)*256+tmp ];
1452                                         //tmp = *pDestBits;
1453                                         //*pDestBits++ = tmp+1;
1454                                         fu += fdu;
1455                                         fv += fdv;
1456                                         fw += fdw;
1457                                         l += dldx;
1458                                 }
1459
1460                         } else {
1461 #if 1
1462                                 tmapscan_lln8( lx, rx, y, p, dp, rp, flags );
1463 #else
1464                                 u = fl2f(p->u*64.0f);
1465                                 v = fl2f(p->v*64.0f);
1466                                 l = fl2f(p->l*32.0f);
1467                                 dudx = fl2f(dp->u*64.0f);
1468                                 dvdx = fl2f(dp->v*64.0f);
1469                                 dldx = fl2f(dp->l*32.0f);
1470
1471                                 for ( count = rx - lx + 1 ; count > 0; count-- )        {
1472                                         
1473                                         //tmp = cdata[((v>>16)&63)*64+((u>>16)&63)];
1474                                         //*pDestBits++ = ;//gr_fade_table[ (l>>16)*256+tmp ];
1475                                         (*pDestBits)++;
1476                                         pDestBits++;
1477                                         u += dudx;
1478                                         v += dvdx;
1479                                         l += dldx;
1480                                 }
1481 #endif
1482                         }
1483                 } else {
1484                         if ( flags & TMAP_FLAG_CORRECT )        {
1485                                 u = fl2f(p->u*64.0f);
1486                                 v = fl2f(p->v*64.0f);
1487                                 w = fl2f(p->sw*16.0f);
1488
1489                                 dudx = fl2f(dp->u*64.0f);
1490                                 dvdx = fl2f(dp->v*64.0f);
1491                                 dwdx = fl2f(dp->sw*16.0f);
1492                                                 
1493                                 for ( count = rx - lx + 1 ; count > 0; count-- )        {
1494                                         tmp = cdata[((v/w)&63)*64+((u/w)&63)];
1495                                         *pDestBits++ = tmp;
1496                                         u += dudx;
1497                                         v += dvdx;
1498                                         w += dwdx;
1499                                 }
1500                         } else {
1501                                 u = fl2f(p->u*64.0f);
1502                                 v = fl2f(p->v*64.0f);
1503                                 dudx = fl2f(dp->u*64.0f);
1504                                 dvdx = fl2f(dp->v*64.0f);
1505
1506                                 for ( count = rx - lx + 1 ; count > 0; count-- )        {
1507                                         tmp = cdata[((v>>16)&63)*64+((u>>16)&63)];
1508                                         *pDestBits++ = tmp;
1509                                         u += dudx;
1510                                         v += dvdx;
1511                                 }
1512                         }
1513                 }
1514         } else {
1515                 if ( Tmap1.flags & TMAP_FLAG_RAMP ) {
1516                                 l = fl2f(p->l*32.0f);
1517                                 dldx = fl2f(dp->l*32.0f);
1518                                                 
1519                                 for ( count = rx - lx + 1 ; count > 0; count-- )        {
1520                                         *pDestBits++ = gr_fade_table[ (l>>16)*256+gr_screen.current_color.raw8 ];
1521                                         l += dldx;
1522                                 }
1523                 } else {
1524                         memset( pDestBits, gr_screen.current_color.raw8, (rx-lx+1) );
1525                 }
1526         }
1527 }
1528
1529 uint testpixel;
1530 uint fsave_area[64];
1531
1532 unsigned __int64 packrgb( int r, int g, int b )
1533 {
1534         unsigned __int64 tmp;
1535         unsigned int *tmps;
1536
1537         tmp = 0;
1538
1539         tmps = (unsigned int *)&r;
1540         tmp |= *tmps & 0xFFFF;
1541         tmp <<= 16;
1542
1543         tmps = (unsigned int *)&g;
1544         tmp |= *tmps & 0xFFFF;
1545         tmp <<= 16;
1546
1547         tmps = (unsigned int *)&b;
1548         tmp |= *tmps & 0xFFFF;
1549
1550         return tmp;
1551 }
1552
1553
1554
1555 void tmapscan_generic( int lx, int rx, int y, vertex *p, vertex *dp,  vertex * rp,uint flags )
1556 {
1557         int count;
1558         uint *pDestBits, tmp, tmp1;
1559         int u, dudx, v, dvdx, w, dwdx;
1560         int r, g, b, dr, dg, db;
1561
1562         if ( !rgbtable_inited )
1563                 rgbtable_init();
1564
1565         pDestBits = GR_SCREEN_PTR(uint,lx,y);
1566
1567         if ( Tmap1.flags & TMAP_FLAG_TEXTURED ) {
1568                 uint * cdata = (uint *)tmap_bitmap->data;
1569
1570                 if ( Tmap1.flags & TMAP_FLAG_GOURAUD ) {
1571                         if ( Tmap1.flags & TMAP_FLAG_CORRECT )  {
1572                                 u = fl2f(p->u*64.0f);
1573                                 v = fl2f(p->v*64.0f);
1574                                 w = fl2f(p->sw);
1575
1576                                 r = fl2f(p->r*255.0f);
1577                                 g = fl2f(p->g*255.0f);
1578                                 b = fl2f(p->b*255.0f);
1579
1580                                 dr = fl2f(dp->r*255.0f);
1581                                 dg = fl2f(dp->g*255.0f);
1582                                 db = fl2f(dp->b*255.0f);
1583
1584                                 dudx = fl2f(dp->u*64.0f);
1585                                 dvdx = fl2f(dp->v*64.0f);
1586                                 dwdx = fl2f(dp->sw);
1587                                         
1588                                 for ( count = rx - lx + 1 ; count > 0; count-- )        {
1589                                         tmp = cdata[((v/w)&63)*64+((u/w)&63)];
1590                                         tmp1 = rgbtable1[ (tmp & 0xFF)+ (b>>16) ];
1591                                         tmp1 |= rgbtable2[ ((tmp>>8) & 0xFF)+ (g>>16) ];
1592                                         tmp1 |= rgbtable3[ ((tmp>>16) & 0xFF)+ (r>>16) ];
1593                                         *pDestBits++ = tmp1;
1594                                         u += dudx;
1595                                         v += dvdx;
1596                                         w += dwdx;
1597                                         r += dr;
1598                                         g += dg;
1599                                         b += db;
1600                                 }
1601                         } else {
1602                                 // MMX!!!
1603                                 __int64 light, deltalight;
1604
1605                                 u = fl2f(p->u*64.0f);
1606                                 v = fl2f(p->v*64.0f);
1607                                 dudx = fl2f(dp->u*64.0f);
1608                                 dvdx = fl2f(dp->v*64.0f);
1609
1610 #if 0
1611                                 r = fl2f(p->r*255.0f)>>8;
1612                                 g = fl2f(p->g*255.0f)>>8;
1613                                 b = fl2f(p->b*255.0f)>>8;
1614
1615                                 dr = fl2f(dp->r*255.0f)>>8;
1616                                 dg = fl2f(dp->g*255.0f)>>8;
1617                                 db = fl2f(dp->b*255.0f)>>8;
1618 #else
1619                                 r = fl2f(p->r)>>7;
1620                                 g = fl2f(p->g)>>7;
1621                                 b = fl2f(p->b)>>7;
1622
1623                                 dr = fl2f(dp->r)>>7;
1624                                 dg = fl2f(dp->g)>>7;
1625                                 db = fl2f(dp->b)>>7;
1626
1627                                 //r = 256*2;
1628                                 //g = 256*2;
1629                                 //b = 256*2;
1630                                 //dr = dg = db = 0;
1631 #endif
1632                                 
1633                                 light = packrgb( r, g, b );
1634                                 deltalight = packrgb( dr, dg, db );
1635
1636                                 _asm fstenv fsave_area
1637                                 _asm movq       mm3, light
1638                                 _asm movq       mm4, deltalight
1639                                 _asm pxor       mm2, mm2                        ; mm0 = 0
1640
1641                                 for ( count = rx - lx + 1 ; count > 0; count-- )        {
1642                                         testpixel = cdata[((v>>16)&63)*64+((u>>16)&63)];
1643
1644                                         _asm punpcklbw  mm2, testpixel  ; mm0 = 8.8,8.8, 8.8 rgb
1645                                         _asm pmulhw             mm2, mm3                        ;
1646                                         _asm paddsw             mm3, mm4                        ; light += deltalight
1647                                         _asm packuswb   mm2, mm2                        ;mm2 is who cares
1648                                         _asm movd               testpixel, mm2  ; load tmp
1649                                         _asm pxor               mm2, mm2                        ; mm0 = 0
1650
1651                                         *pDestBits++ = testpixel;
1652                                         u += dudx;
1653                                         v += dvdx;
1654                                 }
1655                                 _asm emms
1656                                 _asm frstor fsave_area
1657                         }
1658                 } else {
1659                         if ( Tmap1.flags & TMAP_FLAG_CORRECT )  {
1660                                 u = fl2f(p->u*64.0f);
1661                                 v = fl2f(p->v*64.0f);
1662                                 w = fl2f(p->sw);
1663                                 dudx = fl2f(dp->u*64.0f);
1664                                 dvdx = fl2f(dp->v*64.0f);
1665                                 dwdx = fl2f(dp->sw);
1666                                         
1667                                 for ( count = rx - lx + 1 ; count > 0; count-- )        {
1668                                         *pDestBits++ = cdata[((v/w)&63)*64+((u/w)&63)];
1669                                         u += dudx;
1670                                         v += dvdx;
1671                                         w += dwdx;
1672                                 }
1673                         } else {
1674                                 u = fl2f(p->u*64.0f);
1675                                 v = fl2f(p->v*64.0f);
1676                                 dudx = fl2f(dp->u*64.0f);
1677                                 dvdx = fl2f(dp->v*64.0f);
1678                                 
1679                                 for ( count = rx - lx + 1 ; count > 0; count-- )        {
1680                                         *pDestBits++ = cdata[((v>>16)&63)*64+((u>>16)&63)];
1681                                         u += dudx;
1682                                         v += dvdx;
1683                                 }
1684                         }
1685                 }
1686         } else if ( Tmap1.flags & TMAP_FLAG_GOURAUD ) {
1687
1688                 r = fl2f(p->r*255.0f);
1689                 g = fl2f(p->g*255.0f);
1690                 b = fl2f(p->b*255.0f);
1691
1692                 dr = fl2f(dp->r*255.0f);
1693                 dg = fl2f(dp->g*255.0f);
1694                 db = fl2f(dp->b*255.0f);
1695                 
1696                 for ( count = rx - lx + 1 ; count > 0; count-- )        {
1697                         *pDestBits++ = (r&0xFF0000)|((g>>8)&0xFF00)|(b>>16);
1698                         r += dr;
1699                         g += dg;
1700                         b += db;
1701                         //*pDestBits++ = 100;
1702                 }
1703         } else {
1704                 memset( pDestBits, gr_screen.current_color.raw32, (rx-lx+1)*4 );
1705         }
1706 }
1707
1708 void tmapscan_flat( int lx, int rx, int y, vertex *p, vertex *dp,  vertex * rp,uint flags )
1709 {
1710         int w;
1711         uint *pDestBits;
1712         
1713         pDestBits = GR_SCREEN_PTR(uint,lx,y);
1714         w = (rx-lx+1);
1715 #ifdef USE_INLINE_ASM
1716         _asm    mov     eax, gr_screen.current_color.raw32
1717         _asm    mov     ecx, w
1718         _asm    mov     edi, pDestBits
1719         _asm    cld
1720         _asm    rep     stosd
1721 #else
1722         for (i=0; i<w; i++ )    {
1723                 *pDestBits++ = gr_screen.current_color.raw32;
1724         }
1725 #endif
1726 }
1727
1728 float zbuffer[640*480];
1729
1730 void zbuffer_clear()
1731 {
1732         int i;
1733         for (i=0; i<640*480; i++ )
1734                 zbuffer[i] = 10000.0f;
1735 }
1736
1737 void tmapscan_flat_z( int lx, int rx, int y, vertex *p, vertex *dp,  vertex * rp,uint flags )
1738 {
1739         int w;
1740         uint *pDestBits;
1741         float * tz;
1742         float z, dz;
1743
1744         tz = &zbuffer[y*640+lx];
1745         pDestBits = GR_SCREEN_PTR(uint,lx,y);
1746         w = (rx-lx+1);
1747         z = p->z;
1748         dz = dp->z;
1749 //#ifdef USE_INLINE_ASM
1750 #if 0
1751         _asm    mov     eax, gr_screen.current_color.raw32
1752         _asm    mov     ecx, w
1753         _asm    mov     edi, pDestBits
1754         _asm    cld
1755         _asm    rep     stosd
1756 #else
1757         { int i;
1758                 for (i=0; i<w; i++ )    {
1759                         if ( z < *tz )  {
1760                                 *tz = z;
1761                                 *pDestBits = gr_screen.current_color.raw32;
1762                         }
1763                         pDestBits++;
1764                         tz++;
1765                         z += dz;
1766                 }
1767         }
1768 #endif
1769 }
1770
1771
1772
1773 #define NBITS 4
1774
1775 uint fsave_area1[64];
1776
1777 void tmapscan_pln( int lx, int rx, int y, vertex *p, vertex *dp,  vertex * rp,uint flags )
1778 {
1779         __int64 light, deltalight;
1780         int r, g, b, dr, dg, db;
1781         _fx_srcptr = (uint)tmap_bitmap->data;
1782         _fx_destptr = (uint)GR_SCREEN_PTR(uint,lx,y);
1783         _loop_count = rx - lx;
1784         _fx_u = fl2f(p->u*64.0f);
1785         _fx_v = fl2f(p->v*64.0f);
1786         _fx_w = fl2f(p->sw*16.0);
1787         _fx_du = fl2f(dp->u*64.0f);
1788         _fx_dv = fl2f(dp->v*64.0f);
1789         _fx_dw = fl2f(dp->sw*16.0);
1790
1791         _fx_u_right = fl2f(rp->u*64.0f);
1792         _fx_v_right = fl2f(rp->v*64.0f); 
1793         _fx_w_right = fl2f(rp->sw*16.0);
1794
1795         r = fl2f(p->r)>>7;
1796         g = fl2f(p->g)>>7;
1797         b = fl2f(p->b)>>7;
1798
1799         dr = fl2f(dp->r)>>7;
1800         dg = fl2f(dp->g)>>7;
1801         db = fl2f(dp->b)>>7;
1802
1803         light = ((__int64)r<<32)|((__int64)g<<16)|(__int64)b;
1804         deltalight = ((__int64)dr<<32)|((__int64)dg<<16)|(__int64)db;
1805
1806         _asm fstenv fsave_area1
1807         _asm movq       mm3, light
1808         _asm movq       mm4, deltalight
1809         
1810         _asm {
1811         push    eax
1812         push    ecx
1813         push    edx
1814         push    ebx
1815         push    ebp
1816         push    esi
1817         push    edi
1818         
1819         mov     ebx,_fx_u
1820         mov     ebp,_fx_v
1821         mov     ecx,_fx_w
1822         mov     edi,_fx_destptr
1823
1824 ; compute initial v coordinate
1825         mov     eax,ebp ; get v
1826         mov     edx,eax
1827         sar     edx,16
1828         shl     eax,16
1829         idiv    ecx     ; eax = (v/z)
1830         mov     V0, eax
1831
1832 ; compute initial u coordinate
1833         mov     eax,ebx ; get u
1834         mov     edx,eax
1835         sar     edx,16
1836         shl     eax,16
1837         idiv    ecx     ; eax = (v/z)
1838         mov     U0, eax
1839
1840         mov     ecx, _fx_w
1841
1842 ; find number of subdivisions
1843         mov     eax, _loop_count
1844         inc     eax
1845         mov     esi, eax
1846         and     esi, 15
1847         sar     eax, NBITS
1848         mov     num_left_over, esi
1849         jz      DoEndPixels     ;there are no 2^NBITS chunks, do divide/pixel for whole scanline
1850         mov     _loop_count, eax
1851
1852 ; Set deltas to NPIXS pixel increments
1853         mov     eax, _fx_du
1854         shl     eax, NBITS
1855         mov     DU1, eax
1856         mov     eax, _fx_dv
1857         shl     eax, NBITS
1858         mov     DV1, eax
1859         mov     eax, _fx_dw
1860         shl     eax, NBITS
1861         mov     DZ1, eax
1862
1863         align   4
1864 TopOfLoop4:
1865         add     ebx, DU1
1866         add     ebp, DV1
1867         add     ecx, DZ1
1868
1869 ; Done with ebx, ebp, ecx until next iteration
1870         push    ebx
1871         push    ecx
1872         push    ebp
1873         push    edi
1874
1875
1876 ; Find fixed U1         
1877         mov     eax, ebx
1878         mov     edx,eax
1879         sar     edx,16
1880         shl     eax,16
1881         idiv    ecx     ; eax = (v/z)
1882         mov     ebx, eax        ; ebx = U1 until pop's
1883
1884 ; Find fixed V1         
1885         mov     eax, ebp
1886         mov     edx,eax
1887         sar     edx,16
1888         shl     eax,16
1889         idiv    ecx     ; eax = (v/z)
1890         mov     ebp, eax        ; ebx = V1 until pop's
1891
1892 ; Get last correct U,Vs
1893         mov     ecx, U0 ; ecx = U0 until pop's
1894         mov     edi, V0 ; edi = V0 until pop's
1895
1896 ; Make ESI =  V0:U0 in 6:10,6:10 format
1897         mov     eax, edi
1898         shr     eax, 6
1899         mov     esi, ecx
1900         shl     esi, 10
1901         mov     si, ax
1902                 
1903 ; Make EDX = DV:DU in 6:10,6:10 format
1904         mov     eax, ebp
1905         sub     eax, edi
1906         sar     eax, NBITS+6
1907         mov     edx, ebx
1908         sub     edx, ecx
1909         shl     edx, 10-NBITS   ; EDX = V1-V0/ 4 in 6:10 int:frac
1910         mov     dx, ax  ; put delta u in low word
1911
1912 ; Save the U1 and V1 so we don't have to divide on the next iteration
1913         mov     U0, ebx
1914         mov     V0, ebp
1915
1916         pop     edi     ; Restore EDI before using it
1917                 
1918         mov     ecx, _fx_srcptr
1919         mov     ebx, 1 << NBITS
1920
1921 PixelRun:
1922         mov                     eax, esi
1923         shr                     ax, 10
1924         rol                     eax, 6
1925         and                     eax, 0ffffh
1926         add                     esi, edx
1927         movd                    mm1, [eax*4+ecx]        
1928         pxor                    mm2, mm2        ; mm2 = 0
1929         punpcklbw       mm2, mm1        ; mm0 = 8.8,8.8, 8.8 rgb
1930         pmulhw          mm2, mm3
1931         paddsw          mm3, mm4        ; light += deltalight
1932         packuswb                mm2, mm2        ;mm2 is who cares
1933         movd                    [edi], mm2      ; load tmp
1934         add                     edi, 4
1935         dec                     ebx
1936         jnz                     PixelRun
1937         
1938         pop     ebp
1939         pop     ecx
1940         pop     ebx
1941         dec     _loop_count
1942         jnz     TopOfLoop4
1943
1944 ;EndOfLoop4:
1945
1946         test    num_left_over, -1
1947         je      _none_to_do
1948
1949         cmp     num_left_over, 4
1950         ja      DoEndPixels
1951
1952         ; If less than 4, then just keep interpolating without
1953         ; calculating a new DU:DV.
1954         mov     ecx, _fx_srcptr
1955         jmp     FinishOff
1956
1957 ; ----------------------------------------- Start of LeftOver Pixels ------------------------------------------
1958 DoEndPixels:
1959
1960         push    edi
1961         mov     ecx, _fx_w_right
1962
1963 ; Find fixed U1         
1964         mov     eax, _fx_u_right
1965         mov     edx,eax
1966         sar     edx,16
1967         shl     eax,16
1968         idiv    ecx     ; eax = (v/z)
1969         mov     ebx, eax        ; ebx = U1 until pop's
1970
1971 ; Find fixed V1         
1972         mov     eax, _fx_v_right
1973         mov     edx,eax
1974         sar     edx,16
1975         shl     eax,16
1976         idiv    ecx     ; eax = (v/z)
1977         mov     ebp, eax        ; ebp = V1 until pop's
1978
1979         mov     ecx, U0 ; ecx = U0 until pop's
1980         mov     edi, V0 ; edi = V0 until pop's
1981
1982 ; Make EDX = DV:DU in 6:10,6:10 format
1983         mov     eax, ebx
1984         sub     eax, ecx
1985         mov     edx, eax        ; These two lines are faster than cdq
1986         sar     edx, 31         
1987         idiv    num_left_over   ; eax = (v1-v0)/num_left_over
1988         shl     eax, 16-6       ; go from 16.16 to 6.10, and move into high 16 bits
1989         mov     esi, eax        ; esi = dvdx<<16
1990
1991         mov     eax, ebp
1992         sub     eax, edi
1993         mov     edx, eax        ; These two lines are faster than cdq
1994         sar     edx, 31         
1995         idiv    num_left_over   ; eax = (u1-u0)/num_left_over
1996         sar     eax, 6          ; go from 16.16 to 6.10 (ax=dvdx in 6.10)
1997         mov     si, ax          ; esi = dvdx:dudx
1998         mov     edx, esi
1999
2000 ; Make ESI =  V0:U0 in 6:10,6:10 format
2001         mov     eax, edi
2002         shr     eax, 6
2003         mov     esi, ecx
2004         shl     esi, 10
2005         mov     si, ax
2006         
2007         pop     edi     ; Restore EDI before using it
2008                 
2009 ; LIGHTING CODE
2010         mov     ecx, _fx_srcptr
2011
2012 FinishOff:
2013         mov     eax, esi
2014         shr     ax, 10
2015         rol     eax, 6
2016         and     eax, 0ffffh
2017         add     esi, edx
2018 ;       mov eax, [eax*4+ecx]
2019 ;       mov [edi],eax           
2020         movd                    mm1, [eax*4+ecx]        
2021         pxor                    mm2, mm2        ; mm2 = 0
2022         punpcklbw       mm2, mm1        ; mm0 = 8.8,8.8, 8.8 rgb
2023         pmulhw          mm2, mm3
2024         paddsw          mm3, mm4        ; light += deltalight
2025         packuswb                mm2, mm2        ;mm2 is who cares
2026         movd                    [edi], mm2      ; load tmp
2027         add     edi, 4
2028         
2029         dec     num_left_over
2030         jnz     FinishOff
2031
2032
2033 _none_to_do:    
2034         pop     edi
2035         pop     esi
2036         pop     ebp
2037         pop     ebx
2038         pop     edx
2039         pop     ecx
2040         pop     eax
2041         }       // end asm
2042
2043         _asm emms
2044         _asm frstor fsave_area1
2045 }
2046
2047
2048 void tmapscan_lln( int lx, int rx, int y, vertex *p, vertex *dp,  vertex * rp,uint flags )
2049 {
2050         __int64 light, deltalight;
2051         int r, g, b, dr, dg, db;
2052         _fx_srcptr = (uint)tmap_bitmap->data;
2053         _fx_destptr = (uint)GR_SCREEN_PTR(uint,lx,y);
2054         _loop_count = rx - lx;
2055         _fx_u = fl2f(p->u*64.0f);
2056         _fx_v = fl2f(p->v*64.0f);
2057         _fx_du = fl2f(dp->u*64.0f);
2058         _fx_dv = fl2f(dp->v*64.0f);
2059
2060         r = fl2f(p->r)>>7;
2061         g = fl2f(p->g)>>7;
2062         b = fl2f(p->b)>>7;
2063
2064         dr = fl2f(dp->r)>>7;
2065         dg = fl2f(dp->g)>>7;
2066         db = fl2f(dp->b)>>7;
2067
2068         light = ((__int64)r<<32)|((__int64)g<<16)|(__int64)b;
2069         deltalight = ((__int64)dr<<32)|((__int64)dg<<16)|(__int64)db;
2070
2071         _asm fstenv fsave_area1
2072         _asm movq       mm3, light
2073         _asm movq       mm4, deltalight
2074         
2075         _asm {
2076         push    eax
2077         push    ecx
2078         push    edx
2079         push    ebx
2080         push    ebp
2081         push    esi
2082         push    edi
2083         
2084         mov     ebx,_fx_u
2085         mov     ebp,_fx_v
2086         mov     edi,_fx_destptr
2087
2088 ; find number of subdivisions
2089         mov     eax, _loop_count
2090         inc     eax
2091         jz              none_to_do
2092         mov     _loop_count, eax
2093
2094 ; Make ESI =  V0:U0 in 6:10,6:10 format
2095         mov     eax, edi
2096         shr     eax, 6
2097         mov     esi, ecx
2098         shl     esi, 10
2099         mov     si, ax
2100                 
2101 ; Make EDX = DV:DU in 6:10,6:10 format
2102         mov     eax, ebp
2103         sub     eax, edi
2104         sar     eax, NBITS+6
2105         mov     edx, ebx
2106         sub     edx, ecx
2107         shl     edx, 10-NBITS   ; EDX = V1-V0/ 4 in 6:10 int:frac
2108         mov     dx, ax  ; put delta u in low word
2109
2110         mov     ecx, _fx_srcptr
2111         mov     ebx, _loop_count
2112
2113 PixelRun:
2114         mov                     eax, esi
2115         shr                     ax, 10
2116         rol                     eax, 6
2117         and                     eax, 0ffffh
2118         add                     esi, edx
2119         movd                    mm1, [eax*4+ecx]        
2120         pxor                    mm2, mm2        ; mm2 = 0
2121         punpcklbw       mm2, mm1        ; mm0 = 8.8,8.8, 8.8 rgb
2122         pmulhw          mm2, mm3
2123         paddsw          mm3, mm4        ; light += deltalight
2124         packuswb                mm2, mm2        ;mm2 is who cares
2125         movd                    [edi], mm2      ; load tmp
2126         add                     edi, 4
2127         dec                     ebx
2128         jnz                     PixelRun
2129
2130 none_to_do:
2131
2132         pop     edi
2133         pop     esi
2134         pop     ebp
2135         pop     ebx
2136         pop     edx
2137         pop     ecx
2138         pop     eax
2139         }       // end asm
2140
2141         _asm emms
2142         _asm frstor fsave_area1
2143 }
2144
2145
2146
2147
2148 void tmapscan_pln8_tiled( int lx, int rx, int y, vertex *p, vertex *dp,  vertex * rp,uint flags )
2149 {
2150         Tmap1.dest_row_data = GR_SCREEN_PTR(ubyte,lx,y);
2151         Tmap1.loop_count = rx - lx;
2152         Tmap1.fx_u = fl2f(p->u);
2153         Tmap1.fx_v = fl2f(p->v);
2154         Tmap1.fx_du_dx = fl2f(dp->u);
2155         Tmap1.fx_dv_dx = fl2f(dp->v);
2156
2157         Tmap1.fx_l = fl2f(p->l*32.0); 
2158         Tmap1.fx_dl_dx = fl2f(dp->l*32.0);
2159
2160         Tmap1.fx_u_right = fl2f(rp->u);
2161         Tmap1.fx_v_right = fl2f(rp->v);
2162         Tmap1.pixptr = (unsigned char *)tmap_bitmap->data;
2163         Tmap1.bp = tmap_bitmap;
2164         Tmap1.src_offset = tmap_bitmap->w;
2165
2166
2167         Tmap1.FixedScale = 65536.0f;
2168         Tmap1.FixedScale8 =     2048.0f;        //8192.0f;      // 2^16 / 8
2169         Tmap1.One = 1.0f;
2170
2171
2172    Tmap1.UOverZ = p->u;
2173         Tmap1.VOverZ = p->v;
2174         Tmap1.OneOverZ = p->sw;
2175
2176         Tmap1.dUOverZdX8 = dp->u*32.0f;
2177         Tmap1.dVOverZdX8 = dp->v*32.0f;
2178         Tmap1.dOneOverZdX8 = dp->sw*32.0f;
2179
2180         Tmap1.dUOverZdX = dp->u;
2181         Tmap1.dVOverZdX = dp->v;
2182         Tmap1.dOneOverZdX = dp->sw;
2183
2184    Tmap1.RightUOverZ = rp->u;
2185         Tmap1.RightVOverZ = rp->v;
2186         Tmap1.RightOneOverZ = rp->sw;
2187
2188         Tmap1.BitmapWidth = Tmap1.bp->w;
2189         Tmap1.BitmapHeight = Tmap1.bp->h;
2190
2191         if (Tmap1.BitmapWidth!=64) return;
2192         if (Tmap1.BitmapHeight!=64) return;
2193
2194
2195
2196         if ( Tmap1.fx_dl_dx < 0 )       {
2197                 Tmap1.fx_dl_dx = -Tmap1.fx_dl_dx;
2198                 Tmap1.fx_l = (67*F1_0)-Tmap1.fx_l;
2199                 Tmap1.fx_l_right = (67*F1_0)-Tmap1.fx_l_right;
2200         }
2201
2202
2203         _asm {
2204         
2205         push    eax
2206         push    ecx
2207         push    edx
2208         push    ebx
2209         push    ebp
2210         push    esi
2211         push    edi
2212
2213
2214         // put the FPU in 32 bit mode
2215         // @todo move this out of here!
2216
2217         fstcw           Tmap1.OldFPUCW                                  // store copy of CW
2218         mov             ax,Tmap1.OldFPUCW                               // get it in ax
2219 //hh    and             eax,NOT 1100000000y                     // 24 bit precision
2220         and             eax, ~0x300L
2221         mov             Tmap1.FPUCW,ax                                  // store it
2222         fldcw           Tmap1.FPUCW                                             // load the FPU
2223
2224         mov             ecx, Tmap1.loop_count           // ecx = width
2225         inc             ecx
2226         mov             edi, Tmap1.dest_row_data        // edi = dest pointer
2227
2228         // edi = pointer to start pixel in dest dib
2229         // ecx = spanwidth
2230
2231         mov             eax,ecx                                                 // eax and ecx = width
2232         shr             ecx,5                                                           // ecx = width / subdivision length
2233         and             eax,31                                                          // eax = width mod subdivision length
2234         jnz             some_left_over                                  // any leftover?
2235 //      jmp             Return
2236         dec             ecx                                                             // no, so special case last span
2237         mov             eax,32                                                          // it's 8 pixels long
2238 some_left_over:
2239         mov             Tmap1.Subdivisions,ecx          // store widths
2240         mov             Tmap1.WidthModLength,eax
2241     
2242 //    mov     ebx,pLeft                   ; get left edge pointer
2243 //    mov     edx,pGradients              ; get gradients pointer
2244
2245         // calculate ULeft and VLeft                    // FPU Stack (ZL = ZLeft)
2246                                                                                                         // st0  st1  st2  st3  st4  st5  st6  st7
2247         fld             Tmap1.VOverZ                                    // V/ZL 
2248         fld             Tmap1.UOverZ                                    // U/ZL V/ZL 
2249         fld             Tmap1.OneOverZ                                  // 1/ZL U/ZL V/ZL 
2250         fld1                                                                                    // 1    1/ZL U/ZL V/ZL 
2251         fdiv            st,st(1)                                                        // ZL   1/ZL U/ZL V/ZL 
2252         fld             st                                                                      // ZL   ZL   1/ZL U/ZL V/ZL 
2253         fmul            st,st(4)                                                        // VL   ZL   1/ZL U/ZL V/ZL 
2254         fxch            st(1)                                                           // ZL   VL   1/ZL U/ZL V/ZL 
2255         fmul            st,st(3)                                                        // UL   VL   1/ZL U/ZL V/ZL 
2256
2257         fstp            st(5)                                                           // VL   1/ZL U/ZL V/ZL UL
2258         fstp            st(5)                                                           // 1/ZL U/ZL V/ZL UL   VL
2259
2260         // calculate right side OverZ terms  ; st0  st1  st2  st3  st4  st5  st6  st7
2261
2262         fadd            Tmap1.dOneOverZdX8                      // 1/ZR U/ZL V/ZL UL   VL
2263         fxch            st(1)                                                           // U/ZL 1/ZR V/ZL UL   VL
2264         fadd            Tmap1.dUOverZdX8                                // U/ZR 1/ZR V/ZL UL   VL
2265         fxch            st(2)                                                           // V/ZL 1/ZR U/ZR UL   VL
2266         fadd            Tmap1.dVOverZdX8                                // V/ZR 1/ZR U/ZR UL   VL
2267
2268         // calculate right side coords          // st0  st1  st2  st3  st4  st5  st6  st7
2269
2270         fld1                                                                                    // 1    V/ZR 1/ZR U/ZR UL   VL
2271         // @todo overlap this guy
2272         fdiv            st,st(2)                                                        // ZR   V/ZR 1/ZR U/ZR UL   VL
2273         fld             st                                                                      // ZR   ZR   V/ZR 1/ZR U/ZR UL   VL
2274         fmul            st,st(2)                                                        // VR   ZR   V/ZR 1/ZR U/ZR UL   VL
2275         fxch            st(1)                                                           // ZR   VR   V/ZR 1/ZR U/ZR UL   VL
2276         fmul            st,st(4)                                                        // UR   VR   V/ZR 1/ZR U/ZR UL   VL
2277
2278         cmp             ecx,0                                                   // check for any full spans
2279         jle      HandleLeftoverPixels
2280     
2281 SpanLoop:
2282
2283         // at this point the FPU contains       // st0  st1  st2  st3  st4  st5  st6  st7
2284                                                                                                         // UR   VR   V/ZR 1/ZR U/ZR UL   VL
2285
2286         // convert left side coords
2287
2288         fld     st(5)                       ; UL   UR   VR   V/ZR 1/ZR U/ZR UL   VL
2289         fmul    Tmap1.FixedScale            ; UL16 UR   VR   V/ZR 1/ZR U/ZR UL   VL
2290         fistp   Tmap1.UFixed                ; UR   VR   V/ZR 1/ZR U/ZR UL   VL
2291
2292         fld     st(6)                       ; VL   UR   VR   V/ZR 1/ZR U/ZR UL   VL
2293         fmul    Tmap1.FixedScale            ; VL16 UR   VR   V/ZR 1/ZR U/ZR UL   VL
2294         fistp   Tmap1.VFixed                ; UR   VR   V/ZR 1/ZR U/ZR UL   VL
2295
2296         // calculate deltas                  ; st0  st1  st2  st3  st4  st5  st6  st7
2297
2298         fsubr   st(5),st                    ; UR   VR   V/ZR 1/ZR U/ZR dU   VL
2299         fxch    st(1)                       ; VR   UR   V/ZR 1/ZR U/ZR dU   VL
2300         fsubr   st(6),st                    ; VR   UR   V/ZR 1/ZR U/ZR dU   dV
2301         fxch    st(6)                       ; dV   UR   V/ZR 1/ZR U/ZR dU   VR
2302
2303         fmul    Tmap1.FixedScale8           ; dV8  UR   V/ZR 1/ZR U/ZR dU   VR
2304         fistp   Tmap1.DeltaV                ; UR   V/ZR 1/ZR U/ZR dU   VR
2305
2306         fxch    st(4)                       ; dU   V/ZR 1/ZR U/ZR UR   VR
2307         fmul    Tmap1.FixedScale8           ; dU8  V/ZR 1/ZR U/ZR UR   VR
2308         fistp   Tmap1.DeltaU                ; V/ZR 1/ZR U/ZR UR   VR
2309
2310         // increment terms for next span     ; st0  st1  st2  st3  st4  st5  st6  st7
2311         // Right terms become Left terms---->; V/ZL 1/ZL U/ZL UL   VL
2312
2313         fadd    Tmap1.dVOverZdX8            ; V/ZR 1/ZL U/ZL UL   VL
2314         fxch    st(1)                       ; 1/ZL V/ZR U/ZL UL   VL
2315         fadd    Tmap1.dOneOverZdX8          ; 1/ZR V/ZR U/ZL UL   VL
2316         fxch    st(2)                       ; U/ZL V/ZR 1/ZR UL   VL
2317         fadd    Tmap1.dUOverZdX8            ; U/ZR V/ZR 1/ZR UL   VL
2318         fxch    st(2)                       ; 1/ZR V/ZR U/ZR UL   VL
2319         fxch    st(1)                       ; V/ZR 1/ZR U/ZR UL   VL
2320
2321         ; calculate right side coords       ; st0  st1  st2  st3  st4  st5  st6  st7
2322
2323         fld1                                ; 1    V/ZR 1/ZR U/ZR UL   VL
2324         fdiv    st,st(2)                    ; ZR   V/ZR 1/ZR U/ZR UL   VL
2325
2326
2327     ; ************** Can't Access Stack Frame ******************
2328     ; ************** Can't Access Stack Frame ******************
2329     ; ************** Can't Access Stack Frame ******************
2330
2331     // 8 pixel span code
2332     // edi = dest dib bits at current pixel
2333     // esi = texture pointer at current u,v
2334     // eax = scratch
2335     // ebx = u fraction 0.32
2336     // ecx = v fraction 0.32
2337     // edx = u frac step
2338     // ebp = v carry scratch
2339
2340         //need to have:
2341         // eax = ?
2342         // ebx = l in 24.8
2343         // ecx = source pixels
2344         // edx = u v  in 6.10 6.10
2345         // esi = du dv in 6.10 6.10
2346         // edi = dest pixels
2347         // ebp = dldx in 24.8
2348
2349
2350         mov     eax, Tmap1.fx_l
2351         shr     eax, 8
2352         mov     ebx, eax
2353
2354         mov     ebp, Tmap1.fx_dl_dx
2355         shl     ebp, 5  //*32
2356         add     Tmap1.fx_l, ebp
2357
2358         mov     ebp, Tmap1.fx_l
2359         shr     ebp, 8
2360         sub     ebp, eax
2361         shr     ebp, 5
2362
2363         mov     ecx, Tmap1.pixptr       // ecx = source pixels
2364
2365 ; Make ESI =  DV:DU in 6:10,6:10 format
2366         mov     eax, Tmap1.DeltaU
2367         shr     eax, 6
2368         mov     esi, Tmap1.DeltaV
2369         shl     esi, 10
2370         mov     si, ax
2371                 
2372 ; Make EDX = DV:DU in 6:10,6:10 format
2373
2374         mov     eax, Tmap1.UFixed
2375         shr     eax, 6
2376         mov     edx, Tmap1.VFixed
2377         shl     edx, 10
2378         mov     dx, ax
2379
2380         ; Draw 32 pixels
2381
2382                 ; pixel 0
2383                 mov     eax, edx        
2384                 shr     ax, 10
2385                 rol     eax, 6
2386                 and     eax, 0ffffh
2387                 add     edx, esi
2388                 mov     al, [ecx+eax]                   
2389                 mov     ah, bh          
2390                 add     ebx, ebp
2391                 mov     al, gr_fade_table[eax]
2392                 mov     [edi+0], al
2393
2394                 ; pixel 1
2395                 mov     eax, edx        
2396                 shr     ax, 10
2397                 rol     eax, 6
2398                 and     eax, 0ffffh
2399                 add     edx, esi
2400                 mov     al, [ecx+eax]                   
2401                 mov     ah, bh          
2402                 add     ebx, ebp
2403                 mov     al, gr_fade_table[eax]
2404                 mov     [edi+1], al
2405
2406                 ; pixel 2
2407                 mov     eax, edx        
2408                 shr     ax, 10
2409                 rol     eax, 6
2410                 and     eax, 0ffffh
2411                 add     edx, esi
2412                 mov     al, [ecx+eax]                   
2413                 mov     ah, bh          
2414                 add     ebx, ebp
2415                 mov     al, gr_fade_table[eax]
2416                 mov     [edi+2], al
2417
2418                 ; pixel 3
2419                 mov     eax, edx        
2420                 shr     ax, 10
2421                 rol     eax, 6
2422                 and     eax, 0ffffh
2423                 add     edx, esi
2424                 mov     al, [ecx+eax]                   
2425                 mov     ah, bh          
2426                 add     ebx, ebp
2427                 mov     al, gr_fade_table[eax]
2428                 mov     [edi+3], al
2429
2430                 ; pixel 4
2431                 mov     eax, edx        
2432                 shr     ax, 10
2433                 rol     eax, 6
2434                 and     eax, 0ffffh
2435                 add     edx, esi
2436                 mov     al, [ecx+eax]                   
2437                 mov     ah, bh          
2438                 add     ebx, ebp
2439                 mov     al, gr_fade_table[eax]
2440                 mov     [edi+4], al
2441
2442                 ; pixel 5
2443                 mov     eax, edx        
2444                 shr     ax, 10
2445                 rol     eax, 6
2446                 and     eax, 0ffffh
2447                 add     edx, esi
2448                 mov     al, [ecx+eax]                   
2449                 mov     ah, bh          
2450                 add     ebx, ebp
2451                 mov     al, gr_fade_table[eax]
2452                 mov     [edi+5], al
2453
2454                 ; pixel 6
2455                 mov     eax, edx        
2456                 shr     ax, 10
2457                 rol     eax, 6
2458                 and     eax, 0ffffh
2459                 add     edx, esi
2460                 mov     al, [ecx+eax]                   
2461                 mov     ah, bh          
2462                 add     ebx, ebp
2463                 mov     al, gr_fade_table[eax]
2464                 mov     [edi+6], al
2465
2466                 ; pixel 7
2467                 mov     eax, edx        
2468                 shr     ax, 10
2469                 rol     eax, 6
2470                 and     eax, 0ffffh
2471                 add     edx, esi
2472                 mov     al, [ecx+eax]                   
2473                 mov     ah, bh          
2474                 add     ebx, ebp
2475                 mov     al, gr_fade_table[eax]
2476                 mov     [edi+7], al
2477
2478                 ; pixel 8
2479                 mov     eax, edx        
2480                 shr     ax, 10
2481                 rol     eax, 6
2482                 and     eax, 0ffffh
2483                 add     edx, esi
2484                 mov     al, [ecx+eax]                   
2485                 mov     ah, bh          
2486                 add     ebx, ebp
2487                 mov     al, gr_fade_table[eax]
2488                 mov     [edi+8], al
2489
2490                 ; pixel 9
2491                 mov     eax, edx        
2492                 shr     ax, 10
2493                 rol     eax, 6
2494                 and     eax, 0ffffh
2495                 add     edx, esi
2496                 mov     al, [ecx+eax]                   
2497                 mov     ah, bh          
2498                 add     ebx, ebp
2499                 mov     al, gr_fade_table[eax]
2500                 mov     [edi+9], al
2501
2502                 ; pixel 10
2503                 mov     eax, edx        
2504                 shr     ax, 10
2505                 rol     eax, 6
2506                 and     eax, 0ffffh
2507                 add     edx, esi
2508                 mov     al, [ecx+eax]                   
2509                 mov     ah, bh          
2510                 add     ebx, ebp
2511                 mov     al, gr_fade_table[eax]
2512                 mov     [edi+10], al
2513
2514                 ; pixel 11
2515                 mov     eax, edx        
2516                 shr     ax, 10
2517                 rol     eax, 6
2518                 and     eax, 0ffffh
2519                 add     edx, esi
2520                 mov     al, [ecx+eax]                   
2521                 mov     ah, bh          
2522                 add     ebx, ebp
2523                 mov     al, gr_fade_table[eax]
2524                 mov     [edi+11], al
2525
2526                 ; pixel 12
2527                 mov     eax, edx        
2528                 shr     ax, 10
2529                 rol     eax, 6
2530                 and     eax, 0ffffh
2531                 add     edx, esi
2532                 mov     al, [ecx+eax]                   
2533                 mov     ah, bh          
2534                 add     ebx, ebp
2535                 mov     al, gr_fade_table[eax]
2536                 mov     [edi+12], al
2537
2538                 ; pixel 13
2539                 mov     eax, edx        
2540                 shr     ax, 10
2541                 rol     eax, 6
2542                 and     eax, 0ffffh
2543                 add     edx, esi
2544                 mov     al, [ecx+eax]                   
2545                 mov     ah, bh          
2546                 add     ebx, ebp
2547                 mov     al, gr_fade_table[eax]
2548                 mov     [edi+13], al
2549
2550                 ; pixel 14
2551                 mov     eax, edx        
2552                 shr     ax, 10
2553                 rol     eax, 6
2554                 and     eax, 0ffffh
2555                 add     edx, esi
2556                 mov     al, [ecx+eax]                   
2557                 mov     ah, bh          
2558                 add     ebx, ebp
2559                 mov     al, gr_fade_table[eax]
2560                 mov     [edi+14], al
2561
2562                 ; pixel 15
2563                 mov     eax, edx        
2564                 shr     ax, 10
2565                 rol     eax, 6
2566                 and     eax, 0ffffh
2567                 add     edx, esi
2568                 mov     al, [ecx+eax]                   
2569                 mov     ah, bh          
2570                 add     ebx, ebp
2571                 mov     al, gr_fade_table[eax]
2572                 mov     [edi+15], al
2573
2574                 ; pixel 16
2575                 mov     eax, edx        
2576                 shr     ax, 10
2577                 rol     eax, 6
2578                 and     eax, 0ffffh
2579                 add     edx, esi
2580                 mov     al, [ecx+eax]                   
2581                 mov     ah, bh          
2582                 add     ebx, ebp
2583                 mov     al, gr_fade_table[eax]
2584                 mov     [edi+16], al
2585
2586                 ; pixel 17
2587                 mov     eax, edx        
2588                 shr     ax, 10
2589                 rol     eax, 6
2590                 and     eax, 0ffffh
2591                 add     edx, esi
2592                 mov     al, [ecx+eax]                   
2593                 mov     ah, bh          
2594                 add     ebx, ebp
2595                 mov     al, gr_fade_table[eax]
2596                 mov     [edi+17], al
2597
2598                 ; pixel 18
2599                 mov     eax, edx        
2600                 shr     ax, 10
2601                 rol     eax, 6
2602                 and     eax, 0ffffh
2603                 add     edx, esi
2604                 mov     al, [ecx+eax]                   
2605                 mov     ah, bh          
2606                 add     ebx, ebp
2607                 mov     al, gr_fade_table[eax]
2608                 mov     [edi+18], al
2609
2610                 ; pixel 19
2611                 mov     eax, edx        
2612                 shr     ax, 10
2613                 rol     eax, 6
2614                 and     eax, 0ffffh
2615                 add     edx, esi
2616                 mov     al, [ecx+eax]                   
2617                 mov     ah, bh          
2618                 add     ebx, ebp
2619                 mov     al, gr_fade_table[eax]
2620                 mov     [edi+19], al
2621
2622                 ; pixel 20
2623                 mov     eax, edx        
2624                 shr     ax, 10
2625                 rol     eax, 6
2626                 and     eax, 0ffffh
2627                 add     edx, esi
2628                 mov     al, [ecx+eax]                   
2629                 mov     ah, bh          
2630                 add     ebx, ebp
2631                 mov     al, gr_fade_table[eax]
2632                 mov     [edi+20], al
2633
2634                 ; pixel 21
2635                 mov     eax, edx        
2636                 shr     ax, 10
2637                 rol     eax, 6
2638                 and     eax, 0ffffh
2639                 add     edx, esi
2640                 mov     al, [ecx+eax]                   
2641                 mov     ah, bh          
2642                 add     ebx, ebp
2643                 mov     al, gr_fade_table[eax]
2644                 mov     [edi+21], al
2645
2646                 ; pixel 22
2647                 mov     eax, edx        
2648                 shr     ax, 10
2649                 rol     eax, 6
2650                 and     eax, 0ffffh
2651                 add     edx, esi
2652                 mov     al, [ecx+eax]                   
2653                 mov     ah, bh          
2654                 add     ebx, ebp
2655                 mov     al, gr_fade_table[eax]
2656                 mov     [edi+22], al
2657
2658                 ; pixel 23
2659                 mov     eax, edx        
2660                 shr     ax, 10
2661                 rol     eax, 6
2662                 and     eax, 0ffffh
2663                 add     edx, esi
2664                 mov     al, [ecx+eax]                   
2665                 mov     ah, bh          
2666                 add     ebx, ebp
2667                 mov     al, gr_fade_table[eax]
2668                 mov     [edi+23], al
2669
2670                 ; pixel 24
2671                 mov     eax, edx        
2672                 shr     ax, 10
2673                 rol     eax, 6
2674                 and     eax, 0ffffh
2675                 add     edx, esi
2676                 mov     al, [ecx+eax]                   
2677                 mov     ah, bh          
2678                 add     ebx, ebp
2679                 mov     al, gr_fade_table[eax]
2680                 mov     [edi+24], al
2681
2682                 ; pixel 25
2683                 mov     eax, edx        
2684                 shr     ax, 10
2685                 rol     eax, 6
2686                 and     eax, 0ffffh
2687                 add     edx, esi
2688                 mov     al, [ecx+eax]                   
2689                 mov     ah, bh          
2690                 add     ebx, ebp
2691                 mov     al, gr_fade_table[eax]
2692                 mov     [edi+25], al
2693
2694                 ; pixel 26
2695                 mov     eax, edx        
2696                 shr     ax, 10
2697                 rol     eax, 6
2698                 and     eax, 0ffffh
2699                 add     edx, esi
2700                 mov     al, [ecx+eax]                   
2701                 mov     ah, bh          
2702                 add     ebx, ebp
2703                 mov     al, gr_fade_table[eax]
2704                 mov     [edi+26], al
2705
2706                 ; pixel 27
2707                 mov     eax, edx        
2708                 shr     ax, 10
2709                 rol     eax, 6
2710                 and     eax, 0ffffh
2711                 add     edx, esi
2712                 mov     al, [ecx+eax]                   
2713                 mov     ah, bh          
2714                 add     ebx, ebp
2715                 mov     al, gr_fade_table[eax]
2716                 mov     [edi+27], al
2717
2718                 ; pixel 28
2719                 mov     eax, edx        
2720                 shr     ax, 10
2721                 rol     eax, 6
2722                 and     eax, 0ffffh
2723                 add     edx, esi
2724                 mov     al, [ecx+eax]                   
2725                 mov     ah, bh          
2726                 add     ebx, ebp
2727                 mov     al, gr_fade_table[eax]
2728                 mov     [edi+28], al
2729
2730                 ; pixel 29
2731                 mov     eax, edx        
2732                 shr     ax, 10
2733                 rol     eax, 6
2734                 and     eax, 0ffffh
2735                 add     edx, esi
2736                 mov     al, [ecx+eax]                   
2737                 mov     ah, bh          
2738                 add     ebx, ebp
2739                 mov     al, gr_fade_table[eax]
2740                 mov     [edi+29], al
2741
2742                 ; pixel 30
2743                 mov     eax, edx        
2744                 shr     ax, 10
2745                 rol     eax, 6
2746                 and     eax, 0ffffh
2747                 add     edx, esi
2748                 mov     al, [ecx+eax]                   
2749                 mov     ah, bh          
2750                 add     ebx, ebp
2751                 mov     al, gr_fade_table[eax]
2752                 mov     [edi+30], al
2753
2754                 ; pixel 31
2755                 mov     eax, edx        
2756                 shr     ax, 10
2757                 rol     eax, 6
2758                 and     eax, 0ffffh
2759                 add     edx, esi
2760                 mov     al, [ecx+eax]                   
2761                 mov     ah, bh          
2762                 add     ebx, ebp
2763                 mov     al, gr_fade_table[eax]
2764                 mov     [edi+31], al
2765
2766     
2767     ; ************** Okay to Access Stack Frame ****************
2768     ; ************** Okay to Access Stack Frame ****************
2769     ; ************** Okay to Access Stack Frame ****************
2770
2771
2772     ; the fdiv is done, finish right    ; st0  st1  st2  st3  st4  st5  st6  st7
2773                                         ; ZR   V/ZR 1/ZR U/ZR UL   VL
2774
2775     fld     st                          ; ZR   ZR   V/ZR 1/ZR U/ZR UL   VL
2776     fmul    st,st(2)                    ; VR   ZR   V/ZR 1/ZR U/ZR UL   VL
2777     fxch    st(1)                       ; ZR   VR   V/ZR 1/ZR U/ZR UL   VL
2778     fmul    st,st(4)                    ; UR   VR   V/ZR 1/ZR U/ZR UL   VL
2779
2780     add     edi,32                       ; increment to next span
2781     dec     Tmap1.Subdivisions              ; decrement span count
2782     jnz     SpanLoop                    ; loop back
2783
2784 HandleLeftoverPixels:
2785
2786     mov     esi,Tmap1.pixptr          ; load texture pointer
2787
2788     ; edi = dest dib bits
2789     ; esi = current texture dib bits
2790     ; at this point the FPU contains    ; st0  st1  st2  st3  st4  st5  st6  st7
2791     ; inv. means invalid numbers        ; inv. inv. inv. inv. inv. UL   VL
2792
2793     cmp     Tmap1.WidthModLength,0          ; are there remaining pixels to draw?
2794     jz      FPUReturn                   ; nope, pop the FPU and bail
2795
2796     ; convert left side coords          ; st0  st1  st2  st3  st4  st5  st6  st7
2797
2798     fld     st(5)                       ; UL   inv. inv. inv. inv. inv. UL   VL
2799     fmul    Tmap1.FixedScale                ; UL16 inv. inv. inv. inv. inv. UL   VL
2800     fistp   Tmap1.UFixed                    ; inv. inv. inv. inv. inv. UL   VL
2801
2802     fld     st(6)                       ; VL   inv. inv. inv. inv. inv. UL   VL
2803     fmul    Tmap1.FixedScale                // VL16 inv. inv. inv. inv. inv. UL   VL
2804     fistp   Tmap1.VFixed                    ; inv. inv. inv. inv. inv. UL   VL
2805
2806     dec     Tmap1.WidthModLength            ; calc how many steps to take
2807     jz      OnePixelSpan                ; just one, don't do deltas
2808
2809     ; calculate right edge coordinates  ; st0  st1  st2  st3  st4  st5  st6  st7
2810     ; r -> R+1
2811
2812     ; @todo rearrange things so we don't need these two instructions
2813     fstp    Tmap1.FloatTemp                 ; inv. inv. inv. inv. UL   VL
2814     fstp    Tmap1.FloatTemp                 ; inv. inv. inv. UL   VL
2815
2816     fld     Tmap1.RightVOverZ           ; V/Zr inv. inv. inv. UL   VL
2817     fsub    Tmap1.dVOverZdX             ; V/ZR inv. inv. inv. UL   VL
2818     fld     Tmap1.RightUOverZ           ; U/Zr V/ZR inv. inv. inv. UL   VL
2819     fsub    Tmap1.dUOverZdX             ; U/ZR V/ZR inv. inv. inv. UL   VL
2820     fld     Tmap1.RightOneOverZ              ; 1/Zr U/ZR V/ZR inv. inv. inv. UL   VL
2821     fsub    Tmap1.dOneOverZdX           ; 1/ZR U/ZR V/ZR inv. inv. inv. UL   VL
2822
2823     fdivr   Tmap1.One                       ; ZR   U/ZR V/ZR inv. inv. inv. UL   VL
2824
2825     fmul    st(1),st                    ; ZR   UR   V/ZR inv. inv. inv. UL   VL
2826     fmulp   st(2),st                    ; UR   VR   inv. inv. inv. UL   VL
2827
2828     ; calculate deltas                  ; st0  st1  st2  st3  st4  st5  st6  st7
2829
2830     fsubr   st(5),st                    ; UR   VR   inv. inv. inv. dU   VL
2831     fxch    st(1)                       ; VR   UR   inv. inv. inv. dU   VL
2832     fsubr   st(6),st                    ; VR   UR   inv. inv. inv. dU   dV
2833     fxch    st(6)                       ; dV   UR   inv. inv. inv. dU   VR
2834
2835     fidiv   Tmap1.WidthModLength            ; dv   UR   inv. inv. inv. dU   VR
2836     fmul    Tmap1.FixedScale                ; dv16 UR   inv. inv. inv. dU   VR
2837     fistp   Tmap1.DeltaV                    ; UR   inv. inv. inv. dU   VR
2838
2839     fxch    st(4)                       ; dU   inv. inv. inv. UR   VR
2840     fidiv   Tmap1.WidthModLength            ; du   inv. inv. inv. UR   VR
2841     fmul    Tmap1.FixedScale                ; du16 inv. inv. inv. UR   VR
2842     fistp   Tmap1.DeltaU                    ; inv. inv. inv. UR   VR
2843
2844     ; @todo gross!  these are to line up with the other loop
2845     fld     st(1)                       ; inv. inv. inv. inv. UR   VR
2846     fld     st(2)                       ; inv. inv. inv. inv. inv. UR   VR
2847
2848
2849 OnePixelSpan:
2850         mov     eax, Tmap1.fx_l
2851         shr     eax, 8
2852         mov     ebx, eax
2853
2854         mov     ebp, Tmap1.fx_dl_dx
2855         shl     ebp, 5  //*32
2856         add     Tmap1.fx_l, ebp
2857
2858         mov     ebp, Tmap1.fx_l
2859         shr     ebp, 8
2860         sub     ebp, eax
2861         shr     ebp, 5
2862
2863
2864 ; Make ESI =  DV:DU in 6:10,6:10 format
2865         mov     eax, Tmap1.DeltaU
2866         shr     eax, 6
2867         mov     esi, Tmap1.DeltaV
2868         shl     esi, 10
2869         mov     si, ax
2870                 
2871 ; Make EDX = DV:DU in 6:10,6:10 format
2872
2873         mov     eax, Tmap1.UFixed
2874         shr     eax, 6
2875         mov     edx, Tmap1.VFixed
2876         shl     edx, 10
2877         mov     dx, ax
2878
2879         mov     ecx, Tmap1.pixptr       // ecx = source pixels
2880
2881         inc     Tmap1.WidthModLength
2882         mov     eax,Tmap1.WidthModLength
2883         shr     eax, 1
2884         jz              one_more_pix
2885         pushf
2886         mov     Tmap1.WidthModLength, eax
2887
2888
2889 NextPixel:
2890
2891         ; Draw two pixels
2892
2893                 ; pixel 0
2894                 mov     eax, edx        
2895                 shr     ax, 10
2896                 rol     eax, 6
2897                 and     eax, 0ffffh
2898                 add     edx, esi
2899                 mov     al, [ecx+eax]                   
2900                 mov     ah, bh          
2901                 add     ebx, ebp
2902                 mov     al, gr_fade_table[eax]
2903                 mov     [edi+0], al
2904
2905                 ; pixel 1
2906                 mov     eax, edx        
2907                 shr     ax, 10
2908                 rol     eax, 6
2909                 and     eax, 0ffffh
2910                 add     edx, esi
2911                 mov     al, [ecx+eax]                   
2912                 mov     ah, bh          
2913                 add     ebx, ebp
2914                 mov     al, gr_fade_table[eax]
2915                 mov     [edi+1], al
2916
2917
2918         add     edi, 2
2919         dec     Tmap1.WidthModLength
2920         jg              NextPixel
2921
2922         popf
2923         jnc     FPUReturn
2924
2925 one_more_pix:   
2926
2927         ; Draw one pixel
2928         ; pixel 0
2929         mov     eax, edx        
2930         shr     ax, 10
2931         rol     eax, 6
2932         and     eax, 0ffffh
2933         add     edx, esi
2934         mov     al, [ecx+eax]                   
2935         mov     ah, bh          
2936         add     ebx, ebp
2937         mov     al, gr_fade_table[eax]
2938         mov     [edi+0], al
2939
2940 FPUReturn:
2941
2942     ; busy FPU registers:               ; st0  st1  st2  st3  st4  st5  st6  st7
2943                                         ; xxx  xxx  xxx  xxx  xxx  xxx  xxx
2944     ffree   st(0)
2945     ffree   st(1)
2946     ffree   st(2)
2947     ffree   st(3)
2948     ffree   st(4)
2949     ffree   st(5)
2950     ffree   st(6)
2951
2952 //Return:
2953
2954     fldcw   Tmap1.OldFPUCW                  // restore the FPU
2955
2956         pop     edi
2957         pop     esi
2958         pop     ebp
2959         pop     ebx
2960         pop     edx
2961         pop     ecx
2962         pop     eax
2963         }
2964
2965
2966 }
2967
2968 void c_tmap_scanline_flat()
2969 {
2970         switch( gr_screen.bits_per_pixel )      {
2971         case 8:
2972                 #if 1
2973                         memset( Tmap1.dest_row_data, gr_screen.current_color.raw8, Tmap1.loop_count );
2974                 #else
2975                         ubyte *dest;
2976                         int x;
2977
2978                         dest = Tmap1.dest_row_data;
2979
2980                         for (x=Tmap1.loop_count; x >= 0; x-- ) {
2981                                 //(*dest)++;dest++;
2982                                 *dest++ = Tmap1.tmap_flat_color;
2983                         }
2984                 #endif
2985                 break;
2986         case 15:
2987         case 16:
2988                 _asm    mov     ecx, Tmap1.loop_count
2989                 _asm    mov     ax, gr_screen.current_color.raw16;
2990                 _asm    mov     edi, Tmap1.dest_row_data16
2991                 _asm    cld
2992                 _asm    rep     stosw
2993                 break;
2994         case 24:
2995                 _asm    mov     ecx, Tmap1.loop_count
2996                 _asm    mov     ax, gr_screen.current_color.raw16;
2997                 _asm    mov     edi, Tmap1.dest_row_data16
2998                 _asm    cld
2999                 _asm    rep     stosw
3000                 break;
3001         case 32:
3002                 _asm    mov     ecx, Tmap1.loop_count
3003                 _asm    mov     eax, gr_screen.current_color.raw32;
3004                 _asm    mov     edi, Tmap1.dest_row_data32
3005                 _asm    cld
3006                 _asm    rep     stosd
3007                 break;
3008         }
3009
3010 }
3011
3012 void c_tmap_scanline_shaded()
3013 {
3014         int fade;
3015         ubyte *dest;
3016         int x;
3017
3018         dest = Tmap1.dest_row_data;
3019
3020         fade = Tmap1.tmap_flat_shade_value<<8;
3021         for (x=Tmap1.loop_count; x >= 0; x-- ) {
3022                 *dest++ = gr_fade_table[ fade |(*dest)];
3023         }
3024 }
3025
3026 void c_tmap_scanline_lin_nolight()
3027 {
3028         ubyte *dest;
3029         uint c;
3030         int x;
3031         fix u,v,dudx, dvdx;
3032
3033         u = Tmap1.fx_u;
3034         v = Tmap1.fx_v*64;
3035         dudx = Tmap1.fx_du_dx; 
3036         dvdx = Tmap1.fx_dv_dx*64; 
3037
3038         dest = Tmap1.dest_row_data;
3039
3040         if (!Tmap1.Transparency_on)     {
3041                 for (x=Tmap1.loop_count; x >= 0; x-- ) {
3042                         *dest++ = (uint)Tmap1.pixptr[ (f2i(v)&(64*63)) + (f2i(u)&63) ];
3043                         u += dudx;
3044                         v += dvdx;
3045                 }
3046         } else {
3047                 for (x=Tmap1.loop_count; x >= 0; x-- ) {
3048                         c = (uint)Tmap1.pixptr[ (f2i(v)&(64*63)) + (f2i(u)&63) ];
3049                         if ( c!=255)
3050                                 *dest = c;
3051                         dest++;
3052                         u += dudx;
3053                         v += dvdx;
3054                 }
3055         }
3056 }
3057
3058
3059 void c_tmap_scanline_lin()
3060 {
3061
3062 }
3063
3064
3065
3066 void c_tmap_scanline_per_nolight()
3067 {
3068         ubyte *dest;
3069         uint c;
3070         int x;
3071         fix u,v,z,dudx, dvdx, dzdx;
3072
3073         u = Tmap1.fx_u;
3074         v = Tmap1.fx_v*64;
3075         z = Tmap1.fx_z;
3076         dudx = Tmap1.fx_du_dx; 
3077         dvdx = Tmap1.fx_dv_dx*64; 
3078         dzdx = Tmap1.fx_dz_dx;
3079
3080         dest = Tmap1.dest_row_data;
3081
3082         if (!Tmap1.Transparency_on)     {
3083                 for (x=Tmap1.loop_count; x >= 0; x-- ) {
3084                         *dest++ = (uint)Tmap1.pixptr[ ( (v/z)&(64*63) ) + ((u/z)&63) ];
3085                         u += dudx;
3086                         v += dvdx;
3087                         z += dzdx;
3088                 }
3089         } else {
3090                 for (x=Tmap1.loop_count; x >= 0; x-- ) {
3091                         c = (uint)Tmap1.pixptr[ ( (v/z)&(64*63) ) + ((u/z)&63) ];
3092                         if ( c!=255)
3093                                 *dest = c;
3094                         dest++;
3095                         u += dudx;
3096                         v += dvdx;
3097                         z += dzdx;
3098                 }
3099         }
3100 }
3101
3102 void c_tmap_scanline_per1()
3103 {
3104         ubyte *dest;
3105         uint c;
3106         int x;
3107         fix u,v,z,l,dudx, dvdx, dzdx, dldx;
3108
3109         u = Tmap1.fx_u;
3110         v = Tmap1.fx_v*64;
3111         z = Tmap1.fx_z;
3112         dudx = Tmap1.fx_du_dx; 
3113         dvdx = Tmap1.fx_dv_dx*64; 
3114         dzdx = Tmap1.fx_dz_dx;
3115
3116         l = Tmap1.fx_l;
3117         dldx = Tmap1.fx_dl_dx;
3118         dest = Tmap1.dest_row_data;
3119
3120         if (!Tmap1.Transparency_on)     {
3121                 for (x=Tmap1.loop_count; x >= 0; x-- ) {
3122                         *dest++ = gr_fade_table[ (l&(0xff00)) + (uint)Tmap1.pixptr[ ( (v/z)&(64*63) ) + ((u/z)&63) ] ];
3123                         l += dldx;
3124                         u += dudx;
3125                         v += dvdx;
3126                         z += dzdx;
3127                 }
3128         } else {
3129                 for (x=Tmap1.loop_count; x >= 0; x-- ) {
3130                         c = (uint)Tmap1.pixptr[ ( (v/z)&(64*63) ) + ((u/z)&63) ];
3131                         if ( c!=255)
3132                                 *dest = gr_fade_table[ (l&(0xff00)) + c ];
3133                         dest++;
3134                         l += dldx;
3135                         u += dudx;
3136                         v += dvdx;
3137                         z += dzdx;
3138                 }
3139         }
3140 }
3141
3142 #define zonk 1
3143
3144 void c_tmap_scanline_editor()
3145 {
3146         ubyte *dest;
3147         uint c;
3148         int x;
3149         fix u,v,z,dudx, dvdx, dzdx;
3150
3151         u = Tmap1.fx_u;
3152         v = Tmap1.fx_v*64;
3153         z = Tmap1.fx_z;
3154         dudx = Tmap1.fx_du_dx; 
3155         dvdx = Tmap1.fx_dv_dx*64; 
3156         dzdx = Tmap1.fx_dz_dx;
3157
3158         dest = Tmap1.dest_row_data;
3159
3160         if (!Tmap1.Transparency_on)     {
3161                 for (x=Tmap1.loop_count; x >= 0; x-- ) {
3162                         *dest++ = zonk;
3163                         //(uint)pixptr[ ( (v/z)&(64*63) ) + ((u/z)&63) ];
3164                         u += dudx;
3165                         v += dvdx;
3166                         z += dzdx;
3167                 }
3168         } else {
3169                 for (x=Tmap1.loop_count; x >= 0; x-- ) {
3170                         c = (uint)Tmap1.pixptr[ ( (v/z)&(64*63) ) + ((u/z)&63) ];
3171                         if ( c!=255)
3172                                 *dest = zonk;
3173                         dest++;
3174                         u += dudx;
3175                         v += dvdx;
3176                         z += dzdx;
3177                 }
3178         }
3179 }
3180
3181 void asm_tmap_scanline_lln_tiled()
3182 {
3183         if ( Tmap1.BitmapWidth != 64 ) return;
3184         if ( Tmap1.BitmapHeight != 64 ) return;
3185
3186         _asm {
3187         push    eax
3188         push    ecx
3189         push    edx
3190         push    ebx
3191         push    ebp
3192         push    esi
3193         push    edi
3194         
3195         ; set edi = address of first pixel to modify
3196         mov     edi, Tmap1.dest_row_data
3197
3198         mov     eax, Tmap1.fx_v
3199         shr     eax, 6
3200         mov     edx, Tmap1.fx_u
3201         shl     edx, 10
3202         mov     dx, ax          ; EDX=U:V in 6.10 format
3203
3204         mov     eax, Tmap1.fx_dv_dx
3205         shr     eax, 6
3206         mov     esi, Tmap1.fx_du_dx
3207         shl     esi, 10
3208         mov     si, ax          ; ESI=DU:DV in 6.10 format
3209
3210         mov     ebx, Tmap1.fx_l
3211         sar     ebx, 8
3212         mov     ebp, Tmap1.fx_dl_dx
3213         sar     ebp, 8
3214
3215         mov     ecx, Tmap1.pixptr
3216
3217         mov     eax, Tmap1.loop_count
3218         inc     eax
3219         mov     Tmap1.loop_count, eax
3220
3221         shr     eax, 3
3222         je              DoLeftOverPixels
3223
3224         mov     Tmap1.num_big_steps, eax
3225         and     Tmap1.loop_count, 7
3226
3227 NextPixelBlock:
3228                 ; pixel 0
3229                 mov     eax, edx        
3230                 shr     ax, 10
3231                 rol     eax, 6
3232                 and     eax, 0ffffh
3233                 add     edx, esi
3234                 mov     al, [ecx+eax]                   
3235                 mov     ah, bh          
3236                 add     ebx, ebp
3237                 mov     al, gr_fade_table[eax]
3238                 mov     [edi+0], al
3239
3240                 ; pixel 1
3241                 mov     eax, edx        
3242                 shr     ax, 10
3243                 rol     eax, 6
3244                 and     eax, 0ffffh
3245                 add     edx, esi
3246                 mov     al, [ecx+eax]                   
3247                 mov     ah, bh          
3248                 add     ebx, ebp
3249                 mov     al, gr_fade_table[eax]
3250                 mov     [edi+1], al
3251
3252                 ; pixel 2
3253                 mov     eax, edx        
3254                 shr     ax, 10
3255                 rol     eax, 6
3256                 and     eax, 0ffffh
3257                 add     edx, esi
3258                 mov     al, [ecx+eax]                   
3259                 mov     ah, bh          
3260                 add     ebx, ebp
3261                 mov     al, gr_fade_table[eax]
3262                 mov     [edi+2], al
3263
3264                 ; pixel 3
3265                 mov     eax, edx        
3266                 shr     ax, 10
3267                 rol     eax, 6
3268                 and     eax, 0ffffh
3269                 add     edx, esi
3270                 mov     al, [ecx+eax]                   
3271                 mov     ah, bh          
3272                 add     ebx, ebp
3273                 mov     al, gr_fade_table[eax]
3274                 mov     [edi+3], al
3275
3276                 ; pixel 4
3277                 mov     eax, edx        
3278                 shr     ax, 10
3279                 rol     eax, 6
3280                 and     eax, 0ffffh
3281                 add     edx, esi
3282                 mov     al, [ecx+eax]                   
3283                 mov     ah, bh          
3284                 add     ebx, ebp
3285                 mov     al, gr_fade_table[eax]
3286                 mov     [edi+4], al
3287
3288                 ; pixel 5
3289                 mov     eax, edx        
3290                 shr     ax, 10
3291                 rol     eax, 6
3292                 and     eax, 0ffffh
3293                 add     edx, esi
3294                 mov     al, [ecx+eax]                   
3295                 mov     ah, bh          
3296                 add     ebx, ebp
3297                 mov     al, gr_fade_table[eax]
3298                 mov     [edi+5], al
3299
3300                 ; pixel 6
3301                 mov     eax, edx        
3302                 shr     ax, 10
3303                 rol     eax, 6
3304                 and     eax, 0ffffh
3305                 add     edx, esi
3306                 mov     al, [ecx+eax]                   
3307                 mov     ah, bh          
3308                 add     ebx, ebp
3309                 mov     al, gr_fade_table[eax]
3310                 mov     [edi+6], al
3311
3312                 ; pixel 7
3313                 mov     eax, edx        
3314                 shr     ax, 10
3315                 rol     eax, 6
3316                 and     eax, 0ffffh
3317                 add     edx, esi
3318                 mov     al, [ecx+eax]                   
3319                 mov     ah, bh          
3320                 add     ebx, ebp
3321                 mov     al, gr_fade_table[eax]
3322                 mov     [edi+7], al
3323
3324         add     edi, 8
3325         dec     Tmap1.num_big_steps
3326         jne     NextPixelBlock
3327         
3328
3329 DoLeftOverPixels:
3330         mov     eax,Tmap1.loop_count
3331         test    eax, -1
3332         jz      _none_to_do
3333         shr     eax, 1
3334         je      one_more_pix
3335         mov     Tmap1.loop_count, eax
3336         pushf
3337
3338
3339 NextPixel:
3340                 mov     eax, edx        
3341                 shr     ax, 10
3342                 rol     eax, 6
3343                 and     eax, 0ffffh
3344                 add     edx, esi
3345                 mov     al, [ecx+eax]                   
3346                 mov     ah, bh          
3347                 add     ebx, ebp
3348                 mov     al, gr_fade_table[eax]
3349                 mov     [edi+0], al
3350
3351                 mov     eax, edx        
3352                 shr     ax, 10
3353                 rol     eax, 6
3354                 and     eax, 0ffffh
3355                 add     edx, esi
3356                 mov     al, [ecx+eax]                   
3357                 mov     ah, bh          
3358                 add     ebx, ebp
3359                 mov     al, gr_fade_table[eax]
3360                 mov     [edi+1], al
3361
3362
3363         add     edi, 2
3364         dec     Tmap1.loop_count
3365         jne     NextPixel
3366
3367         popf
3368         jnc     _none_to_do
3369
3370 one_more_pix:   
3371         mov     eax, edx        
3372         shr     ax, 10
3373         rol     eax, 6
3374         and     eax, 0ffffh
3375         mov     al, [ecx+eax]                   
3376         mov     ah, bh          
3377         mov     al, gr_fade_table[eax]
3378         mov     [edi], al
3379
3380 _none_to_do:    
3381         pop     edi
3382         pop     esi
3383         pop     ebp
3384         pop     ebx
3385         pop     edx
3386         pop     ecx
3387         pop     eax
3388         }
3389
3390 }
3391
3392 void asm_tmap_scanline_lln32();
3393
3394 void asm_tmap_scanline_lln()
3395 {
3396         int end;
3397
3398 //      return;
3399         if ( Tmap1.tmap_flags & TMAP_FLAG_TILED )       {
3400                 asm_tmap_scanline_lln_tiled();
3401                 return;
3402         }
3403
3404         end = f2i(Tmap1.fx_u);
3405         if ( end >= Tmap1.bp->w ) return;
3406         
3407         end = f2i(Tmap1.fx_v);
3408         if ( end >= Tmap1.bp->h ) return;
3409
3410         end = f2i(Tmap1.fx_u_right);
3411         if ( end >= Tmap1.bp->w ) return;
3412
3413         end = f2i(Tmap1.fx_v_right);
3414         if ( end >= Tmap1.bp->h ) return;
3415
3416         if ( Tmap1.fx_dl_dx < 0 )       {
3417                 Tmap1.fx_dl_dx = -Tmap1.fx_dl_dx;
3418                 Tmap1.fx_l = (67*F1_0)-Tmap1.fx_l;
3419                 Tmap1.fx_l_right = (67*F1_0)-Tmap1.fx_l_right;
3420 //              return;
3421 //              Assert( Tmap1.fx_l > 31*F1_0 );
3422 //              Assert( Tmap1.fx_l < 66*F1_0 );
3423 //              Assert( Tmap1.fx_dl_dx >= 0 );
3424 //              Assert( Tmap1.fx_dl_dx < 31*F1_0 );
3425         }
3426
3427
3428         _asm {
3429         push    eax
3430         push    ecx
3431         push    edx
3432         push    ebx
3433         push    ebp
3434         push    esi
3435         push    edi
3436
3437         ; setup delta values
3438         mov     eax, Tmap1.fx_dv_dx     // get v 16.16 step
3439         mov     ebx, eax                                                // copy it
3440         sar     eax, 16                                         // get v int step
3441         shl     ebx, 16                                         // get v frac step
3442         mov     Tmap1.DeltaVFrac, ebx   // store it
3443         imul    eax, Tmap1.src_offset   // calc texture step for v int step
3444         
3445         mov     ebx, Tmap1.fx_du_dx             // get u 16.16 step
3446         mov     ecx, ebx                                                // copy it
3447         sar     ebx, 16                                         // get the u int step
3448         shl     ecx, 16                                         // get the u frac step
3449         mov     Tmap1.DeltaUFrac, ecx                   // store it
3450         add     eax, ebx                                                // calc uint + vint step
3451         mov     Tmap1.UVintVfracStepVNoCarry, eax       // save whole step in non-v-carry slot
3452         add     eax, Tmap1.src_offset                           // calc whole step + v carry
3453         mov     Tmap1.UVintVfracStepVCarry, eax // save in v-carry slot
3454
3455         ; setup initial coordinates
3456         mov     esi, Tmap1.fx_u                 // get u 16.16
3457         mov     ebx, esi                                                // copy it
3458         sar     esi, 16                                         // get integer part
3459         shl     ebx, 16                                         // get fractional part
3460
3461         mov     ecx, Tmap1.fx_v                 // get v 16.16 
3462         mov     edx, ecx                                                // copy it
3463         sar     edx, 16                                         // get integer part
3464         shl     ecx, 16                                         // get fractional part
3465         imul    edx, Tmap1.src_offset           // calc texture scanline address
3466         add     esi, edx                                                        // calc texture offset
3467         add     esi, Tmap1.pixptr                       // calc address
3468         
3469         ; set edi = address of first pixel to modify
3470         mov     edi, Tmap1.dest_row_data
3471         
3472         mov     edx, Tmap1.DeltaUFrac
3473
3474         mov     eax, Tmap1.loop_count
3475         inc     eax
3476         mov     Tmap1.loop_count, eax
3477
3478         shr     eax, 3
3479         je              DoLeftOverPixels
3480
3481         mov     Tmap1.num_big_steps, eax
3482         and     Tmap1.loop_count, 7
3483
3484
3485 NextPixelBlock:
3486
3487         mov     eax, Tmap1.fx_l
3488         shr     eax, 8
3489         mov     bx, ax
3490
3491         mov     ebp, Tmap1.fx_dl_dx
3492         shl     ebp, 3  //*32
3493         add     Tmap1.fx_l, ebp
3494
3495         mov     ebp, Tmap1.fx_l
3496         shr     ebp, 8
3497         sub     bp, ax
3498         shr     bp, 3
3499
3500         mov     dx, bp
3501
3502
3503     // 8 pixel span code
3504     // edi = dest dib bits at current pixel
3505     // esi = texture pointer at current u,v
3506     // eax = scratch
3507     // ebx = u fraction 0.32
3508     // ecx = v fraction 0.32
3509     // edx = u frac step
3510     // ebp = v carry scratch
3511
3512     mov     al,[edi]                    // preread the destination cache line
3513
3514     mov     al,[esi]                    // get texture pixel 0
3515     mov         ah, bh
3516     mov         al, gr_fade_table[eax]
3517
3518     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
3519     sbb     ebp,ebp                     // get -1 if carry
3520     add     ebx,edx                     // increment u fraction
3521
3522     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
3523     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
3524
3525     sbb     ebp,ebp                     // get -1 if carry
3526     mov     [edi+0],al                  // store pixel 0
3527
3528     add     ebx,edx                     // increment u fraction
3529     mov     al,[esi]                    // get texture pixel 1
3530     mov         ah, bh
3531     mov         al, gr_fade_table[eax]
3532
3533     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
3534     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
3535
3536     sbb     ebp,ebp                     // get -1 if carry
3537     mov     [edi+1],al                  // store pixel 1
3538
3539     add     ebx,edx                     // increment u fraction
3540     mov     al,[esi]                    // get texture pixel 2
3541     mov         ah, bh
3542     mov         al, gr_fade_table[eax]
3543
3544     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
3545     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
3546
3547     sbb     ebp,ebp                     // get -1 if carry
3548     mov     [edi+2],al                  // store pixel 2
3549
3550     add     ebx,edx                     // increment u fraction
3551     mov     al,[esi]                    // get texture pixel 3
3552     mov         ah, bh
3553     mov         al, gr_fade_table[eax]
3554
3555     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
3556     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
3557
3558     sbb     ebp,ebp                     // get -1 if carry
3559     mov     [edi+3],al                  // store pixel 3
3560
3561     add     ebx,edx                     // increment u fraction
3562     mov     al,[esi]                    // get texture pixel 4
3563     mov         ah, bh
3564     mov         al, gr_fade_table[eax]
3565
3566     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
3567     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
3568
3569     sbb     ebp,ebp                     // get -1 if carry
3570     mov     [edi+4],al                  // store pixel 4
3571
3572     add     ebx,edx                     // increment u fraction
3573     mov     al,[esi]                    // get texture pixel 5
3574     mov         ah, bh
3575     mov         al, gr_fade_table[eax]
3576
3577     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
3578     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
3579
3580     sbb     ebp,ebp                     // get -1 if carry
3581     mov     [edi+5],al                  // store pixel 5
3582
3583     add     ebx,edx                     // increment u fraction
3584     mov     al,[esi]                    // get texture pixel 6
3585     mov         ah, bh
3586     mov         al, gr_fade_table[eax]
3587
3588     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
3589     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
3590
3591     sbb     ebp,ebp                     // get -1 if carry
3592     mov     [edi+6],al                  // store pixel 6
3593
3594     add     ebx,edx                     // increment u fraction
3595
3596     mov     al,[esi]                    // get texture pixel 7
3597     mov         ah, bh
3598     mov         al, gr_fade_table[eax]
3599
3600     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
3601
3602     mov     [edi+7],al                 // store pixel 7
3603  
3604                 ; end
3605         
3606
3607         add     edi, 8
3608         dec     Tmap1.num_big_steps
3609         jne     NextPixelBlock
3610         
3611
3612 DoLeftOverPixels:
3613
3614         mov     eax,Tmap1.loop_count
3615         test    eax, -1
3616         jz      _none_to_do
3617         shr     eax, 1
3618         je      one_more_pix
3619         mov     Tmap1.loop_count, eax
3620         pushf
3621
3622         xor     eax, eax
3623
3624
3625         mov     eax, Tmap1.fx_l
3626         shr     eax, 8
3627         mov     bx, ax
3628
3629         mov     ebp, Tmap1.fx_dl_dx
3630         shr     ebp, 8
3631         mov     dx, bp
3632
3633     mov     al,[edi]                    // preread the destination cache line
3634 //    add     ebx,edx                     // increment u fraction
3635
3636 NextPixel:
3637
3638     mov     al,[esi]                    // get texture pixel 0
3639     mov         ah, bh
3640     mov         al, gr_fade_table[eax]
3641
3642     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
3643     sbb     ebp,ebp                     // get -1 if carry
3644     add     ebx,edx                     // increment u fraction
3645     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
3646     mov     [edi+0],al                  // store pixel 0
3647
3648     add     ecx,Tmap1.DeltaVFrac        // increment v fraction
3649     sbb     ebp,ebp                     // get -1 if carry
3650     add     ebx,edx                     // increment u fraction
3651     mov     al,[esi]                    // get texture pixel 1
3652     mov         ah, bh
3653     mov         al, gr_fade_table[eax]
3654
3655     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
3656     mov     [edi+1],al                  // store pixel 1
3657
3658         add     edi, 2
3659         dec     Tmap1.loop_count
3660         jne     NextPixel
3661
3662         popf
3663         jnc     _none_to_do
3664
3665 one_more_pix:   
3666
3667     mov     al,[esi]                    // get texture pixel 2
3668     mov         ah, bh
3669     mov         al, gr_fade_table[eax]
3670     mov     [edi],al                  // store pixel 2
3671
3672 _none_to_do:    
3673         pop     edi
3674         pop     esi
3675         pop     ebp
3676         pop     ebx
3677         pop     edx
3678         pop     ecx
3679         pop     eax
3680         }
3681 }
3682
3683
3684 void asm_tmap_scanline_lln32()
3685 {
3686         int end;
3687
3688         end = f2i(Tmap1.fx_u);
3689         if ( end >= Tmap1.bp->w ) return;
3690         
3691         end = f2i(Tmap1.fx_v);
3692         if ( end >= Tmap1.bp->h ) return;
3693
3694         end = f2i(Tmap1.fx_u_right);
3695         if ( end >= Tmap1.bp->w ) return;
3696
3697         end = f2i(Tmap1.fx_v_right);
3698         if ( end >= Tmap1.bp->h ) return;
3699
3700         _asm {
3701         push    eax
3702         push    ecx
3703         push    edx
3704         push    ebx
3705         push    ebp
3706         push    esi
3707         push    edi
3708
3709         ; setup delta values
3710         mov     eax, Tmap1.fx_dv_dx     // get v 16.16 step
3711         mov     ebx, eax                                                // copy it
3712         sar     eax, 16                                         // get v int step
3713         shl     ebx, 16                                         // get v frac step
3714         mov     Tmap1.DeltaVFrac, ebx   // store it
3715         imul    eax, Tmap1.src_offset   // calc texture step for v int step
3716         
3717         mov     ebx, Tmap1.fx_du_dx             // get u 16.16 step
3718         mov     ecx, ebx                                                // copy it
3719         sar     ebx, 16                                         // get the u int step
3720         shl     ecx, 16                                         // get the u frac step
3721         mov     Tmap1.DeltaUFrac, ecx                   // store it
3722         add     eax, ebx                                                // calc uint + vint step
3723         mov     Tmap1.UVintVfracStepVNoCarry, eax       // save whole step in non-v-carry slot
3724         add     eax, Tmap1.src_offset                           // calc whole step + v carry
3725         mov     Tmap1.UVintVfracStepVCarry, eax // save in v-carry slot
3726
3727         ; setup initial coordinates
3728         mov     esi, Tmap1.fx_u                 // get u 16.16
3729         mov     ebx, esi                                                // copy it
3730         sar     esi, 16                                         // get integer part
3731         shl     ebx, 16                                         // get fractional part
3732
3733         mov     ecx, Tmap1.fx_v                 // get v 16.16 
3734         mov     edx, ecx                                                // copy it
3735         sar     edx, 16                                         // get integer part
3736         shl     ecx, 16                                         // get fractional part
3737         imul    edx, Tmap1.src_offset           // calc texture scanline address
3738         add     esi, edx                                                        // calc texture offset
3739         add     esi, Tmap1.pixptr                       // calc address
3740         
3741         ; set edi = address of first pixel to modify
3742         mov     edi, Tmap1.dest_row_data32
3743         
3744         mov     edx, Tmap1.DeltaUFrac
3745
3746         mov     eax, Tmap1.fx_l // use bx and dx to do lighting
3747         mov     bx, ax
3748         mov     eax, Tmap1.fx_dl_dx     // use bx and dx to do lighting
3749         mov     dx, ax
3750
3751         mov     eax, Tmap1.loop_count
3752         inc     eax
3753         mov     Tmap1.loop_count, eax
3754
3755         shr     eax, 3
3756         je              DoLeftOverPixels
3757
3758         mov     Tmap1.num_big_steps, eax
3759         and     Tmap1.loop_count, 7
3760
3761
3762 NextPixelBlock:
3763
3764     // 8 pixel span code
3765     // edi = dest dib bits at current pixel
3766     // esi = texture pointer at current u,v
3767     // eax = scratch
3768     // ebx = u fraction 0.32
3769     // ecx = v fraction 0.32
3770     // edx = u frac step
3771     // ebp = v carry scratch
3772
3773     mov     al,[edi]                    // preread the destination cache line
3774
3775     mov     al,[esi]                    // get texture pixel 0
3776     mov         ah, bh
3777     mov         eax, gr_fade_table32[eax*4]
3778
3779     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
3780     sbb     ebp,ebp                     // get -1 if carry
3781     add     ebx,edx                     // increment u fraction
3782
3783     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
3784     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
3785
3786     sbb     ebp,ebp                     // get -1 if carry
3787     mov     [edi+0],eax                  // store pixel 0
3788
3789     add     ebx,edx                     // increment u fraction
3790     mov     al,[esi]                    // get texture pixel 1
3791     mov         ah, bh
3792     mov         eax, gr_fade_table32[eax*4]
3793
3794     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
3795     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
3796
3797     sbb     ebp,ebp                     // get -1 if carry
3798     mov     [edi+4],al                  // store pixel 1
3799
3800     add     ebx,edx                     // increment u fraction
3801     mov     al,[esi]                    // get texture pixel 2
3802     mov         ah, bh
3803     mov         eax, gr_fade_table32[eax*4]
3804
3805     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
3806     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
3807
3808     sbb     ebp,ebp                     // get -1 if carry
3809     mov     [edi+8],eax                  // store pixel 2
3810
3811     add     ebx,edx                     // increment u fraction
3812     mov     al,[esi]                    // get texture pixel 3
3813     mov         ah, bh
3814     mov         eax, gr_fade_table32[eax*4]
3815
3816     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
3817     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
3818
3819     sbb     ebp,ebp                     // get -1 if carry
3820     mov     [edi+12],eax                  // store pixel 3
3821
3822     add     ebx,edx                     // increment u fraction
3823     mov     al,[esi]                    // get texture pixel 4
3824     mov         ah, bh
3825     mov         eax, gr_fade_table32[eax*4]
3826
3827     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
3828     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
3829
3830     sbb     ebp,ebp                     // get -1 if carry
3831     mov     [edi+16],eax                  // store pixel 4
3832
3833     add     ebx,edx                     // increment u fraction
3834     mov     al,[esi]                    // get texture pixel 5
3835     mov         ah, bh
3836     mov         eax, gr_fade_table32[eax*4]
3837
3838     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
3839     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
3840
3841     sbb     ebp,ebp                     // get -1 if carry
3842     mov     [edi+20],eax                  // store pixel 5
3843
3844     add     ebx,edx                     // increment u fraction
3845     mov     al,[esi]                    // get texture pixel 6
3846     mov         ah, bh
3847     mov         eax, gr_fade_table32[eax*4]
3848
3849     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
3850     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
3851
3852     sbb     ebp,ebp                     // get -1 if carry
3853     mov     [edi+24],eax                  // store pixel 6
3854
3855     add     ebx,edx                     // increment u fraction
3856
3857     mov     al,[esi]                    // get texture pixel 7
3858     mov         ah, bh
3859     mov         eax, gr_fade_table32[eax]
3860
3861     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
3862
3863     mov     [edi+28],eax                 // store pixel 7
3864  
3865                 ; end
3866         
3867
3868         add     edi, 8*4
3869         dec     Tmap1.num_big_steps
3870         jne     NextPixelBlock
3871         
3872
3873 DoLeftOverPixels:
3874
3875         mov     eax,Tmap1.loop_count
3876         test    eax, -1
3877         jz      _none_to_do
3878         shr     eax, 1
3879         je      one_more_pix
3880         mov     Tmap1.loop_count, eax
3881         pushf
3882
3883         xor     eax, eax
3884
3885 NextPixel:
3886     mov     al,[edi]                    // preread the destination cache line
3887
3888     mov     al,[esi]                    // get texture pixel 0
3889     mov         ah, bh
3890     mov         eax, gr_fade_table32[eax*4]
3891
3892     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
3893     sbb     ebp,ebp                     // get -1 if carry
3894     add     ebx,edx                     // increment u fraction
3895     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
3896     mov     [edi+0],eax                  // store pixel 0
3897
3898     add     ecx,Tmap1.DeltaVFrac        // increment v fraction
3899     sbb     ebp,ebp                     // get -1 if carry
3900     add     ebx,edx                     // increment u fraction
3901     mov     al,[esi]                    // get texture pixel 1
3902     mov         ah, bh
3903     mov         eax, gr_fade_table32[eax*4]
3904
3905     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
3906     mov     [edi+1],al                  // store pixel 1
3907
3908         add     edi, 2*4
3909         dec     Tmap1.loop_count
3910         jne     NextPixel
3911
3912         popf
3913         jnc     _none_to_do
3914
3915 one_more_pix:   
3916
3917     mov     al,[esi]                    // get texture pixel 2
3918     mov         ah, bh
3919     mov         eax, gr_fade_table32[eax*4]
3920     mov     [edi],eax                  // store pixel 2
3921
3922 _none_to_do:    
3923         pop     edi
3924         pop     esi
3925         pop     ebp
3926         pop     ebx
3927         pop     edx
3928         pop     ecx
3929         pop     eax
3930         }
3931 }
3932
3933 void asm_tmap_scanline_lnt()
3934 {
3935         int end;
3936
3937         end = f2i(Tmap1.fx_u);
3938         if ( end >= Tmap1.bp->w ) return;
3939         
3940         end = f2i(Tmap1.fx_v);
3941         if ( end >= Tmap1.bp->h ) return;
3942
3943         end = f2i(Tmap1.fx_u_right);
3944         if ( end >= Tmap1.bp->w ) return;
3945
3946         end = f2i(Tmap1.fx_v_right);
3947         if ( end >= Tmap1.bp->h ) return;
3948
3949
3950         _asm {
3951         push    eax
3952         push    ecx
3953         push    edx
3954         push    ebx
3955         push    ebp
3956         push    esi
3957         push    edi
3958
3959         ; setup delta values
3960         mov     eax, Tmap1.fx_dv_dx     // get v 16.16 step
3961         mov     ebx, eax                                                // copy it
3962         sar     eax, 16                                         // get v int step
3963         shl     ebx, 16                                         // get v frac step
3964         mov     Tmap1.DeltaVFrac, ebx   // store it
3965         imul    eax, Tmap1.src_offset   // calc texture step for v int step
3966         
3967         mov     ebx, Tmap1.fx_du_dx             // get u 16.16 step
3968         mov     ecx, ebx                                                // copy it
3969         sar     ebx, 16                                         // get the u int step
3970         shl     ecx, 16                                         // get the u frac step
3971         mov     Tmap1.DeltaUFrac, ecx                   // store it
3972         add     eax, ebx                                                // calc uint + vint step
3973         mov     Tmap1.UVintVfracStepVNoCarry, eax       // save whole step in non-v-carry slot
3974         add     eax, Tmap1.src_offset                           // calc whole step + v carry
3975         mov     Tmap1.UVintVfracStepVCarry, eax // save in v-carry slot
3976
3977         ; setup initial coordinates
3978         mov     esi, Tmap1.fx_u                 // get u 16.16
3979         mov     ebx, esi                                                // copy it
3980         sar     esi, 16                                         // get integer part
3981         shl     ebx, 16                                         // get fractional part
3982
3983         mov     ecx, Tmap1.fx_v                 // get v 16.16 
3984         mov     edx, ecx                                                // copy it
3985         sar     edx, 16                                         // get integer part
3986         shl     ecx, 16                                         // get fractional part
3987         imul    edx, Tmap1.src_offset           // calc texture scanline address
3988         add     esi, edx                                                        // calc texture offset
3989         add     esi, Tmap1.pixptr                       // calc address
3990         
3991         ; set edi = address of first pixel to modify
3992         mov     edi, Tmap1.dest_row_data
3993         
3994         mov     edx, Tmap1.DeltaUFrac
3995
3996         mov     eax, Tmap1.loop_count
3997         inc     eax
3998         mov     Tmap1.loop_count, eax
3999
4000         shr     eax, 3
4001         je              DoLeftOverPixels
4002
4003         mov     Tmap1.num_big_steps, eax
4004         and     Tmap1.loop_count, 7
4005
4006
4007 NextPixelBlock:
4008
4009     // 8 pixel span code
4010     // edi = dest dib bits at current pixel
4011     // esi = texture pointer at current u,v
4012     // eax = scratch
4013     // ebx = u fraction 0.32
4014     // ecx = v fraction 0.32
4015     // edx = u frac step
4016     // ebp = v carry scratch
4017
4018     mov     al,[edi]                    // preread the destination cache line
4019
4020     mov     al,[esi]                    // get texture pixel 0
4021
4022     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4023     sbb     ebp,ebp                     // get -1 if carry
4024     add     ebx,edx                     // increment u fraction
4025
4026     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4027     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4028
4029     sbb     ebp,ebp                     // get -1 if carry
4030          cmp            al, 255
4031          je             skip0
4032     mov     [edi+0],al                  // store pixel 0
4033 skip0:
4034
4035     add     ebx,edx                     // increment u fraction
4036     mov     al,[esi]                    // get texture pixel 1
4037
4038     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4039     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4040
4041     sbb     ebp,ebp                     // get -1 if carry
4042          cmp            al, 255
4043          je             skip1
4044     mov     [edi+1],al                  // store pixel 0
4045 skip1:
4046
4047     add     ebx,edx                     // increment u fraction
4048     mov     al,[esi]                    // get texture pixel 2
4049
4050     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4051     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4052
4053     sbb     ebp,ebp                     // get -1 if carry
4054          cmp            al, 255
4055          je             skip2
4056     mov     [edi+2],al                  // store pixel 0
4057 skip2:
4058
4059     add     ebx,edx                     // increment u fraction
4060     mov     al,[esi]                    // get texture pixel 3
4061
4062     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4063     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4064
4065     sbb     ebp,ebp                     // get -1 if carry
4066          cmp            al, 255
4067          je             skip3
4068     mov     [edi+3],al                  // store pixel 0
4069 skip3:
4070
4071     add     ebx,edx                     // increment u fraction
4072     mov     al,[esi]                    // get texture pixel 4
4073
4074     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4075     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4076
4077     sbb     ebp,ebp                     // get -1 if carry
4078          cmp            al, 255
4079          je             skip4
4080     mov     [edi+4],al                  // store pixel 0
4081 skip4:
4082
4083     add     ebx,edx                     // increment u fraction
4084     mov     al,[esi]                    // get texture pixel 5
4085
4086     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4087     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4088
4089     sbb     ebp,ebp                     // get -1 if carry
4090          cmp            al, 255
4091          je             skip5
4092     mov     [edi+5],al                  // store pixel 0
4093 skip5:
4094
4095     add     ebx,edx                     // increment u fraction
4096     mov     al,[esi]                    // get texture pixel 6
4097
4098     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4099     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4100
4101     sbb     ebp,ebp                     // get -1 if carry
4102          cmp            al, 255
4103          je             skip6
4104     mov     [edi+6],al                  // store pixel 0
4105 skip6:
4106
4107     add     ebx,edx                     // increment u fraction
4108
4109     mov     al,[esi]                    // get texture pixel 7
4110
4111     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4112
4113          cmp            al, 255
4114          je             skip7
4115     mov     [edi+7],al                  // store pixel 0
4116 skip7:
4117  
4118                 ; end
4119         
4120
4121         add     edi, 8
4122         dec     Tmap1.num_big_steps
4123         jne     NextPixelBlock
4124         
4125
4126 DoLeftOverPixels:
4127
4128         mov     eax,Tmap1.loop_count
4129         test    eax, -1
4130         jz      _none_to_do
4131         shr     eax, 1
4132         je      one_more_pix
4133         mov     Tmap1.loop_count, eax
4134         pushf
4135
4136         xor     eax, eax
4137
4138     mov     al,[edi]                    // preread the destination cache line
4139 //    add     ebx,edx                     // increment u fraction
4140
4141 NextPixel:
4142
4143     mov     al,[esi]                    // get texture pixel 0
4144
4145     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4146     sbb     ebp,ebp                     // get -1 if carry
4147     add     ebx,edx                     // increment u fraction
4148     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4149          cmp            al, 255
4150          je             skipA0
4151     mov     [edi+0],al                  // store pixel 0
4152 skipA0:
4153
4154     add     ecx,Tmap1.DeltaVFrac        // increment v fraction
4155     sbb     ebp,ebp                     // get -1 if carry
4156     add     ebx,edx                     // increment u fraction
4157     mov     al,[esi]                    // get texture pixel 1
4158
4159     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4160          cmp            al, 255
4161          je             skipA1
4162     mov     [edi+1],al                  // store pixel 0
4163 skipA1:
4164
4165         add     edi, 2
4166         dec     Tmap1.loop_count
4167         jne     NextPixel
4168
4169         popf
4170         jnc     _none_to_do
4171
4172 one_more_pix:   
4173
4174     mov     al,[esi]                    // get texture pixel 2
4175          cmp            al, 255
4176          je             skipB
4177     mov     [edi],al                  // store pixel 0
4178 skipB:
4179
4180 _none_to_do:    
4181         pop     edi
4182         pop     esi
4183         pop     ebp
4184         pop     ebx
4185         pop     edx
4186         pop     ecx
4187         pop     eax
4188         }
4189 }
4190
4191
4192 void asm_tmap_scanline_lnn()
4193 {
4194         int end;
4195
4196         end = f2i(Tmap1.fx_u);
4197         if ( end >= Tmap1.bp->w ) return;
4198         
4199         end = f2i(Tmap1.fx_v);
4200         if ( end >= Tmap1.bp->h ) return;
4201
4202         end = f2i(Tmap1.fx_u_right);
4203         if ( end >= Tmap1.bp->w ) return;
4204
4205         end = f2i(Tmap1.fx_v_right);
4206         if ( end >= Tmap1.bp->h ) return;
4207
4208
4209         _asm {
4210         push    eax
4211         push    ecx
4212         push    edx
4213         push    ebx
4214         push    ebp
4215         push    esi
4216         push    edi
4217
4218         ; setup delta values
4219         mov     eax, Tmap1.fx_dv_dx     // get v 16.16 step
4220         mov     ebx, eax                                                // copy it
4221         sar     eax, 16                                         // get v int step
4222         shl     ebx, 16                                         // get v frac step
4223         mov     Tmap1.DeltaVFrac, ebx   // store it
4224         imul    eax, Tmap1.src_offset   // calc texture step for v int step
4225         
4226         mov     ebx, Tmap1.fx_du_dx             // get u 16.16 step
4227         mov     ecx, ebx                                                // copy it
4228         sar     ebx, 16                                         // get the u int step
4229         shl     ecx, 16                                         // get the u frac step
4230         mov     Tmap1.DeltaUFrac, ecx                   // store it
4231         add     eax, ebx                                                // calc uint + vint step
4232         mov     Tmap1.UVintVfracStepVNoCarry, eax       // save whole step in non-v-carry slot
4233         add     eax, Tmap1.src_offset                           // calc whole step + v carry
4234         mov     Tmap1.UVintVfracStepVCarry, eax // save in v-carry slot
4235
4236         ; setup initial coordinates
4237         mov     esi, Tmap1.fx_u                 // get u 16.16
4238         mov     ebx, esi                                                // copy it
4239         sar     esi, 16                                         // get integer part
4240         shl     ebx, 16                                         // get fractional part
4241
4242         mov     ecx, Tmap1.fx_v                 // get v 16.16 
4243         mov     edx, ecx                                                // copy it
4244         sar     edx, 16                                         // get integer part
4245         shl     ecx, 16                                         // get fractional part
4246         imul    edx, Tmap1.src_offset           // calc texture scanline address
4247         add     esi, edx                                                        // calc texture offset
4248         add     esi, Tmap1.pixptr                       // calc address
4249         
4250         ; set edi = address of first pixel to modify
4251         mov     edi, Tmap1.dest_row_data
4252         
4253         mov     edx, Tmap1.DeltaUFrac
4254
4255         mov     eax, Tmap1.loop_count
4256         inc     eax
4257         mov     Tmap1.loop_count, eax
4258
4259         shr     eax, 3
4260         je              DoLeftOverPixels
4261
4262         mov     Tmap1.num_big_steps, eax
4263         and     Tmap1.loop_count, 7
4264
4265
4266 NextPixelBlock:
4267
4268     // 8 pixel span code
4269     // edi = dest dib bits at current pixel
4270     // esi = texture pointer at current u,v
4271     // eax = scratch
4272     // ebx = u fraction 0.32
4273     // ecx = v fraction 0.32
4274     // edx = u frac step
4275     // ebp = v carry scratch
4276
4277     mov     al,[edi]                    // preread the destination cache line
4278
4279     mov     al,[esi]                    // get texture pixel 0
4280
4281     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4282     sbb     ebp,ebp                     // get -1 if carry
4283     add     ebx,edx                     // increment u fraction
4284
4285     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4286     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4287
4288     sbb     ebp,ebp                     // get -1 if carry
4289     mov     [edi+0],al                  // store pixel 0
4290
4291     add     ebx,edx                     // increment u fraction
4292     mov     al,[esi]                    // get texture pixel 1
4293
4294     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4295     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4296
4297     sbb     ebp,ebp                     // get -1 if carry
4298     mov     [edi+1],al                  // store pixel 0
4299
4300     add     ebx,edx                     // increment u fraction
4301     mov     al,[esi]                    // get texture pixel 2
4302
4303     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4304     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4305
4306     sbb     ebp,ebp                     // get -1 if carry
4307     mov     [edi+2],al                  // store pixel 0
4308
4309     add     ebx,edx                     // increment u fraction
4310     mov     al,[esi]                    // get texture pixel 3
4311
4312     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4313     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4314
4315     sbb     ebp,ebp                     // get -1 if carry
4316     mov     [edi+3],al                  // store pixel 0
4317
4318     add     ebx,edx                     // increment u fraction
4319     mov     al,[esi]                    // get texture pixel 4
4320
4321     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4322     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4323
4324     sbb     ebp,ebp                     // get -1 if carry
4325     mov     [edi+4],al                  // store pixel 0
4326
4327     add     ebx,edx                     // increment u fraction
4328     mov     al,[esi]                    // get texture pixel 5
4329
4330     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4331     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4332
4333     sbb     ebp,ebp                     // get -1 if carry
4334     mov     [edi+5],al                  // store pixel 0
4335
4336     add     ebx,edx                     // increment u fraction
4337     mov     al,[esi]                    // get texture pixel 6
4338
4339     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4340     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4341
4342     sbb     ebp,ebp                     // get -1 if carry
4343     mov     [edi+6],al                  // store pixel 0
4344
4345     add     ebx,edx                     // increment u fraction
4346
4347     mov     al,[esi]                    // get texture pixel 7
4348
4349     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4350
4351     mov     [edi+7],al                  // store pixel 0
4352  
4353                 ; end
4354         
4355
4356         add     edi, 8
4357         dec     Tmap1.num_big_steps
4358         jne     NextPixelBlock
4359         
4360
4361 DoLeftOverPixels:
4362
4363         mov     eax,Tmap1.loop_count
4364         test    eax, -1
4365         jz      _none_to_do
4366         shr     eax, 1
4367         je      one_more_pix
4368         mov     Tmap1.loop_count, eax
4369         pushf
4370
4371         xor     eax, eax
4372
4373     mov     al,[edi]                    // preread the destination cache line
4374 //    add     ebx,edx                     // increment u fraction
4375
4376 NextPixel:
4377
4378     mov     al,[esi]                    // get texture pixel 0
4379
4380     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4381     sbb     ebp,ebp                     // get -1 if carry
4382     add     ebx,edx                     // increment u fraction
4383     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4384     mov     [edi+0],al                  // store pixel 0
4385
4386     add     ecx,Tmap1.DeltaVFrac        // increment v fraction
4387     sbb     ebp,ebp                     // get -1 if carry
4388     add     ebx,edx                     // increment u fraction
4389     mov     al,[esi]                    // get texture pixel 1
4390
4391     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4392     mov     [edi+1],al                  // store pixel 0
4393
4394         add     edi, 2
4395         dec     Tmap1.loop_count
4396         jne     NextPixel
4397
4398         popf
4399         jnc     _none_to_do
4400
4401 one_more_pix:   
4402
4403     mov     al,[esi]                    // get texture pixel 2
4404     mov     [edi],al                  // store pixel 0
4405
4406 _none_to_do:    
4407         pop     edi
4408         pop     esi
4409         pop     ebp
4410         pop     ebx
4411         pop     edx
4412         pop     ecx
4413         pop     eax
4414         }
4415 }
4416
4417 void tmapscan_pln16( int lx, int rx, int y, vertex *p, vertex *dp,  vertex * rp,uint flags )
4418 {
4419         Tmap1.dest_row_data = (ubyte *)GR_SCREEN_PTR(ushort,lx,y);
4420         Tmap1.loop_count = rx - lx;
4421         Tmap1.fx_u = fl2f(p->u);
4422         Tmap1.fx_v = fl2f(p->v);
4423         Tmap1.fx_du_dx = fl2f(dp->u);
4424         Tmap1.fx_dv_dx = fl2f(dp->v);
4425
4426         Tmap1.fx_l = fl2f(p->l*32.0); 
4427         Tmap1.fx_dl_dx = fl2f(dp->l*32.0);
4428
4429         Tmap1.fx_u_right = fl2f(rp->u);
4430         Tmap1.fx_v_right = fl2f(rp->v);
4431         Tmap1.pixptr = (unsigned char *)tmap_bitmap->data;
4432         Tmap1.bp = tmap_bitmap;
4433         Tmap1.src_offset = tmap_bitmap->w;
4434
4435
4436         Tmap1.FixedScale = 65536.0f;
4437         Tmap1.FixedScale8 =     2048.0f;        //8192.0f;      // 2^16 / 8
4438         Tmap1.One = 1.0f;
4439
4440
4441    Tmap1.UOverZ = p->u;
4442         Tmap1.VOverZ = p->v;
4443         Tmap1.OneOverZ = p->sw;
4444
4445         Tmap1.dUOverZdX8 = dp->u*32.0f;
4446         Tmap1.dVOverZdX8 = dp->v*32.0f;
4447         Tmap1.dOneOverZdX8 = dp->sw*32.0f;
4448
4449         Tmap1.dUOverZdX = dp->u;
4450         Tmap1.dVOverZdX = dp->v;
4451         Tmap1.dOneOverZdX = dp->sw;
4452
4453    Tmap1.RightUOverZ = rp->u;
4454         Tmap1.RightVOverZ = rp->v;
4455         Tmap1.RightOneOverZ = rp->sw;
4456
4457
4458
4459         Tmap1.BitmapWidth = Tmap1.bp->w;
4460         Tmap1.BitmapHeight = Tmap1.bp->h;
4461
4462
4463         if ( Tmap1.fx_dl_dx < 0 )       {
4464                 Tmap1.fx_dl_dx = -Tmap1.fx_dl_dx;
4465                 Tmap1.fx_l = (67*F1_0)-Tmap1.fx_l;
4466                 Tmap1.fx_l_right = (67*F1_0)-Tmap1.fx_l_right;
4467 //              return;
4468 //              Assert( Tmap1.fx_l > 31*F1_0 );
4469 //              Assert( Tmap1.fx_l < 66*F1_0 );
4470 //              Assert( Tmap1.fx_dl_dx >= 0 );
4471 //              Assert( Tmap1.fx_dl_dx < 31*F1_0 );
4472         }
4473
4474 //      return;
4475
4476
4477
4478         _asm {
4479         
4480         push    eax
4481         push    ecx
4482         push    edx
4483         push    ebx
4484         push    ebp
4485         push    esi
4486         push    edi
4487
4488
4489         // put the FPU in 32 bit mode
4490         // @todo move this out of here!
4491
4492         fstcw           Tmap1.OldFPUCW                                  // store copy of CW
4493         mov             ax,Tmap1.OldFPUCW                               // get it in ax
4494 //hh    and             eax,NOT 1100000000y                     // 24 bit precision
4495         and             eax, ~0x300L
4496         mov             Tmap1.FPUCW,ax                                  // store it
4497         fldcw           Tmap1.FPUCW                                             // load the FPU
4498
4499         mov             ecx, Tmap1.loop_count           // ecx = width
4500         inc             ecx
4501         mov             edi, Tmap1.dest_row_data        // edi = dest pointer
4502
4503         // edi = pointer to start pixel in dest dib
4504         // ecx = spanwidth
4505
4506         mov             eax,ecx                                                 // eax and ecx = width
4507         shr             ecx,5                                                           // ecx = width / subdivision length
4508         and             eax,31                                                          // eax = width mod subdivision length
4509         jnz             some_left_over                                  // any leftover?
4510 //      jmp             Return
4511         dec             ecx                                                             // no, so special case last span
4512         mov             eax,32                                                          // it's 8 pixels long
4513 some_left_over:
4514         mov             Tmap1.Subdivisions,ecx          // store widths
4515         mov             Tmap1.WidthModLength,eax
4516     
4517 //    mov     ebx,pLeft                   ; get left edge pointer
4518 //    mov     edx,pGradients              ; get gradients pointer
4519
4520         // calculate ULeft and VLeft                    // FPU Stack (ZL = ZLeft)
4521                                                                                                         // st0  st1  st2  st3  st4  st5  st6  st7
4522         fld             Tmap1.VOverZ                                    // V/ZL 
4523         fld             Tmap1.UOverZ                                    // U/ZL V/ZL 
4524         fld             Tmap1.OneOverZ                                  // 1/ZL U/ZL V/ZL 
4525         fld1                                                                                    // 1    1/ZL U/ZL V/ZL 
4526         fdiv            st,st(1)                                                        // ZL   1/ZL U/ZL V/ZL 
4527         fld             st                                                                      // ZL   ZL   1/ZL U/ZL V/ZL 
4528         fmul            st,st(4)                                                        // VL   ZL   1/ZL U/ZL V/ZL 
4529         fxch            st(1)                                                           // ZL   VL   1/ZL U/ZL V/ZL 
4530         fmul            st,st(3)                                                        // UL   VL   1/ZL U/ZL V/ZL 
4531
4532         fstp            st(5)                                                           // VL   1/ZL U/ZL V/ZL UL
4533         fstp            st(5)                                                           // 1/ZL U/ZL V/ZL UL   VL
4534
4535         // calculate right side OverZ terms  ; st0  st1  st2  st3  st4  st5  st6  st7
4536
4537         fadd            Tmap1.dOneOverZdX8                      // 1/ZR U/ZL V/ZL UL   VL
4538         fxch            st(1)                                                           // U/ZL 1/ZR V/ZL UL   VL
4539         fadd            Tmap1.dUOverZdX8                                // U/ZR 1/ZR V/ZL UL   VL
4540         fxch            st(2)                                                           // V/ZL 1/ZR U/ZR UL   VL
4541         fadd            Tmap1.dVOverZdX8                                // V/ZR 1/ZR U/ZR UL   VL
4542
4543         // calculate right side coords          // st0  st1  st2  st3  st4  st5  st6  st7
4544
4545         fld1                                                                                    // 1    V/ZR 1/ZR U/ZR UL   VL
4546         // @todo overlap this guy
4547         fdiv            st,st(2)                                                        // ZR   V/ZR 1/ZR U/ZR UL   VL
4548         fld             st                                                                      // ZR   ZR   V/ZR 1/ZR U/ZR UL   VL
4549         fmul            st,st(2)                                                        // VR   ZR   V/ZR 1/ZR U/ZR UL   VL
4550         fxch            st(1)                                                           // ZR   VR   V/ZR 1/ZR U/ZR UL   VL
4551         fmul            st,st(4)                                                        // UR   VR   V/ZR 1/ZR U/ZR UL   VL
4552
4553         cmp             ecx,0                                                   // check for any full spans
4554         jle      HandleLeftoverPixels
4555     
4556 SpanLoop:
4557
4558         // at this point the FPU contains       // st0  st1  st2  st3  st4  st5  st6  st7
4559                                                                                                         // UR   VR   V/ZR 1/ZR U/ZR UL   VL
4560
4561         // convert left side coords
4562
4563         fld     st(5)                       ; UL   UR   VR   V/ZR 1/ZR U/ZR UL   VL
4564         fmul    Tmap1.FixedScale            ; UL16 UR   VR   V/ZR 1/ZR U/ZR UL   VL
4565         fistp   Tmap1.UFixed                ; UR   VR   V/ZR 1/ZR U/ZR UL   VL
4566
4567         fld     st(6)                       ; VL   UR   VR   V/ZR 1/ZR U/ZR UL   VL
4568         fmul    Tmap1.FixedScale            ; VL16 UR   VR   V/ZR 1/ZR U/ZR UL   VL
4569         fistp   Tmap1.VFixed                ; UR   VR   V/ZR 1/ZR U/ZR UL   VL
4570
4571         // calculate deltas                  ; st0  st1  st2  st3  st4  st5  st6  st7
4572
4573         fsubr   st(5),st                    ; UR   VR   V/ZR 1/ZR U/ZR dU   VL
4574         fxch    st(1)                       ; VR   UR   V/ZR 1/ZR U/ZR dU   VL
4575         fsubr   st(6),st                    ; VR   UR   V/ZR 1/ZR U/ZR dU   dV
4576         fxch    st(6)                       ; dV   UR   V/ZR 1/ZR U/ZR dU   VR
4577
4578         fmul    Tmap1.FixedScale8           ; dV8  UR   V/ZR 1/ZR U/ZR dU   VR
4579         fistp   Tmap1.DeltaV                ; UR   V/ZR 1/ZR U/ZR dU   VR
4580
4581         fxch    st(4)                       ; dU   V/ZR 1/ZR U/ZR UR   VR
4582         fmul    Tmap1.FixedScale8           ; dU8  V/ZR 1/ZR U/ZR UR   VR
4583         fistp   Tmap1.DeltaU                ; V/ZR 1/ZR U/ZR UR   VR
4584
4585         // increment terms for next span     ; st0  st1  st2  st3  st4  st5  st6  st7
4586         // Right terms become Left terms---->; V/ZL 1/ZL U/ZL UL   VL
4587
4588         fadd    Tmap1.dVOverZdX8            ; V/ZR 1/ZL U/ZL UL   VL
4589         fxch    st(1)                       ; 1/ZL V/ZR U/ZL UL   VL
4590         fadd    Tmap1.dOneOverZdX8          ; 1/ZR V/ZR U/ZL UL   VL
4591         fxch    st(2)                       ; U/ZL V/ZR 1/ZR UL   VL
4592         fadd    Tmap1.dUOverZdX8            ; U/ZR V/ZR 1/ZR UL   VL
4593         fxch    st(2)                       ; 1/ZR V/ZR U/ZR UL   VL
4594         fxch    st(1)                       ; V/ZR 1/ZR U/ZR UL   VL
4595
4596         ; calculate right side coords       ; st0  st1  st2  st3  st4  st5  st6  st7
4597
4598         fld1                                ; 1    V/ZR 1/ZR U/ZR UL   VL
4599         fdiv    st,st(2)                    ; ZR   V/ZR 1/ZR U/ZR UL   VL
4600
4601
4602     ; set up affine registers
4603
4604     ; setup delta values
4605     
4606     mov     eax,Tmap1.DeltaV                ; get v 16.16 step
4607     mov     ebx,eax                     ; copy it
4608     sar     eax,16                      ; get v int step
4609     shl     ebx,16                      ; get v frac step
4610     mov     Tmap1.DeltaVFrac,ebx            ; store it
4611     imul    eax,Tmap1.src_offset      ; calculate texture step for v int step
4612
4613     mov     ebx,Tmap1.DeltaU                ; get u 16.16 step
4614     mov     ecx,ebx                     ; copy it
4615     sar     ebx,16                      ; get u int step
4616     shl     ecx,16                      ; get u frac step
4617     mov     Tmap1.DeltaUFrac,ecx            ; store it
4618     add     eax,ebx                     ; calculate uint + vint step
4619     mov     Tmap1.UVintVfracStepVNoCarry,eax; save whole step in non-v-carry slot
4620     add     eax,Tmap1.src_offset      ; calculate whole step + v carry
4621     mov     Tmap1.UVintVfracStepVCarry,eax  ; save in v-carry slot
4622
4623
4624 /*
4625 ; check coordinate ranges
4626         mov     eax, Tmap1.UFixed
4627         cmp     eax, Tmap1.MinUFixed
4628         jge     UNotTooSmall_1
4629         mov     eax, Tmap1.MinUFixed
4630         mov     Tmap1.UFixed, eax
4631         jmp     CheckV_1
4632 UNotTooSmall_1: 
4633         cmp     eax, Tmap1.MaxUFixed
4634         jle     CheckV_1
4635         mov     eax, Tmap1.MaxUFixed
4636         mov     Tmap1.UFixed, eax
4637 CheckV_1:
4638         mov     eax, Tmap1.VFixed
4639         cmp     eax, Tmap1.MinVFixed
4640         jge     VNotTooSmall_1
4641         mov     eax, Tmap1.MinVFixed
4642         mov     Tmap1.VFixed, eax
4643         jmp     DoneCheck_1
4644 VNotTooSmall_1: 
4645         cmp     eax, Tmap1.MaxVFixed
4646         jle     DoneCheck_1
4647         mov     eax, Tmap1.MaxVFixed
4648         mov     Tmap1.VFixed, eax
4649 DoneCheck_1:
4650 */
4651     
4652 ; setup initial coordinates
4653     mov     esi,Tmap1.UFixed                ; get u 16.16 fixedpoint coordinate
4654    
4655     mov     ebx,esi                     ; copy it
4656     sar     esi,16                      ; get integer part
4657     shl     ebx,16                      ; get fractional part
4658     
4659     mov     ecx,Tmap1.VFixed                ; get v 16.16 fixedpoint coordinate
4660    
4661     mov     edx,ecx                     ; copy it
4662     sar     edx,16                      ; get integer part
4663     shl     ecx,16                      ; get fractional part
4664     imul    edx,Tmap1.src_offset      ; calc texture scanline address
4665     add     esi,edx                     ; calc texture offset
4666     add     esi,Tmap1.pixptr          ; calc address
4667
4668     mov     edx,Tmap1.DeltaUFrac            ; get register copy
4669
4670         mov     eax, Tmap1.fx_l
4671         shr     eax, 8
4672         mov     bx, ax
4673
4674         mov     ebp, Tmap1.fx_dl_dx
4675         shl     ebp, 5  //*32
4676         add     Tmap1.fx_l, ebp
4677
4678         mov     ebp, Tmap1.fx_l
4679         shr     ebp, 8
4680         sub     bp, ax
4681         shr     bp, 5
4682
4683         mov     dx, bp
4684
4685 //      add     Tmap1.fx_l, eax
4686
4687
4688 //      mov     eax, Tmap1.fx_l // use bx and dx to do lighting
4689 //mov eax, 31*256
4690 //      mov     bx, ax
4691 //      mov     eax, Tmap1.fx_dl_dx     // use bx and dx to do lighting
4692 //mov eax, 0
4693 //      mov     dx, ax
4694
4695
4696
4697     ; ************** Can't Access Stack Frame ******************
4698     ; ************** Can't Access Stack Frame ******************
4699     ; ************** Can't Access Stack Frame ******************
4700
4701     // 8 pixel span code
4702     // edi = dest dib bits at current pixel
4703     // esi = texture pointer at current u,v
4704     // eax = scratch
4705     // ebx = u fraction 0.32
4706     // ecx = v fraction 0.32
4707     // edx = u frac step
4708     // ebp = v carry scratch
4709
4710     mov     al,[edi]                    // preread the destination cache line
4711
4712
4713     mov     al,[esi]                    // get texture pixel 0
4714     mov         ah, bh
4715     mov         ax, gr_fade_table16[eax*2]
4716
4717     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4718     sbb     ebp,ebp                     // get -1 if carry
4719     add     ebx,edx                     // increment u fraction
4720
4721     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4722     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4723
4724     sbb     ebp,ebp                     // get -1 if carry
4725 //      mov al, 0       // Uncomment this line to show divisions
4726     mov     [edi+0],ax                  // store pixel 0
4727
4728     add     ebx,edx                     // increment u fraction
4729     mov     al,[esi]                    // get texture pixel 1
4730     mov         ah, bh
4731     mov         ax, gr_fade_table16[eax*2]
4732
4733     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4734     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4735
4736     sbb     ebp,ebp                     // get -1 if carry
4737     mov     [edi+2],ax                  // store pixel 1
4738
4739     add     ebx,edx                     // increment u fraction
4740     mov     al,[esi]                    // get texture pixel 2
4741     mov         ah, bh
4742     mov         ax, gr_fade_table16[eax*2]
4743
4744     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4745     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4746
4747     sbb     ebp,ebp                     // get -1 if carry
4748     mov     [edi+4],ax                  // store pixel 2
4749
4750     add     ebx,edx                     // increment u fraction
4751     mov     al,[esi]                    // get texture pixel 3
4752     mov         ah, bh
4753     mov         ax, gr_fade_table16[eax*2]
4754
4755     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4756     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4757
4758     sbb     ebp,ebp                     // get -1 if carry
4759     mov     [edi+6],ax                  // store pixel 3
4760
4761     add     ebx,edx                     // increment u fraction
4762     mov     al,[esi]                    // get texture pixel 4
4763     mov         ah, bh
4764     mov         ax, gr_fade_table16[eax*2]
4765     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4766     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4767
4768     sbb     ebp,ebp                     // get -1 if carry
4769     mov     [edi+8],ax                  // store pixel 3
4770
4771     add     ebx,edx                     // increment u fraction
4772     mov     al,[esi]                    // get texture pixel 4
4773     mov         ah, bh
4774     mov         ax, gr_fade_table16[eax*2]
4775     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4776     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4777
4778     sbb     ebp,ebp                     // get -1 if carry
4779     mov     [edi+10],ax                  // store pixel 3
4780
4781     add     ebx,edx                     // increment u fraction
4782     mov     al,[esi]                    // get texture pixel 4
4783     mov         ah, bh
4784     mov         ax, gr_fade_table16[eax*2]
4785     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4786     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4787
4788     sbb     ebp,ebp                     // get -1 if carry
4789     mov     [edi+12],ax                  // store pixel 3
4790
4791     add     ebx,edx                     // increment u fraction
4792     mov     al,[esi]                    // get texture pixel 4
4793     mov         ah, bh
4794     mov         ax, gr_fade_table16[eax*2]
4795     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4796     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4797
4798     sbb     ebp,ebp                     // get -1 if carry
4799     mov     [edi+14],ax                  // store pixel 3
4800
4801     add     ebx,edx                     // increment u fraction
4802     mov     al,[esi]                    // get texture pixel 4
4803     mov         ah, bh
4804     mov         ax, gr_fade_table16[eax*2]
4805     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4806     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4807
4808     sbb     ebp,ebp                     // get -1 if carry
4809     mov     [edi+16],ax                  // store pixel 3
4810
4811     add     ebx,edx                     // increment u fraction
4812     mov     al,[esi]                    // get texture pixel 4
4813     mov         ah, bh
4814     mov         ax, gr_fade_table16[eax*2]
4815     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4816     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4817
4818     sbb     ebp,ebp                     // get -1 if carry
4819     mov     [edi+18],ax                  // store pixel 3
4820
4821     add     ebx,edx                     // increment u fraction
4822     mov     al,[esi]                    // get texture pixel 4
4823     mov         ah, bh
4824     mov         ax, gr_fade_table16[eax*2]
4825     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4826     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4827
4828     sbb     ebp,ebp                     // get -1 if carry
4829     mov     [edi+20],ax                  // store pixel 3
4830
4831     add     ebx,edx                     // increment u fraction
4832     mov     al,[esi]                    // get texture pixel 4
4833     mov         ah, bh
4834     mov         ax, gr_fade_table16[eax*2]
4835
4836
4837     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4838     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4839
4840     sbb     ebp,ebp                     // get -1 if carry
4841     mov     [edi+22],ax                  // store pixel 3
4842
4843     add     ebx,edx                     // increment u fraction
4844     mov     al,[esi]                    // get texture pixel 4
4845     mov         ah, bh
4846     mov         ax, gr_fade_table16[eax*2]
4847
4848
4849     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4850     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4851
4852     sbb     ebp,ebp                     // get -1 if carry
4853     mov     [edi+24],ax                  // store pixel 3
4854
4855     add     ebx,edx                     // increment u fraction
4856     mov     al,[esi]                    // get texture pixel 4
4857     mov         ah, bh
4858     mov         ax, gr_fade_table16[eax*2]
4859
4860
4861     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4862     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4863
4864     sbb     ebp,ebp                     // get -1 if carry
4865     mov     [edi+26],ax                  // store pixel 3
4866
4867     add     ebx,edx                     // increment u fraction
4868     mov     al,[esi]                    // get texture pixel 4
4869     mov         ah, bh
4870     mov         ax, gr_fade_table16[eax*2]
4871
4872
4873     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4874     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4875
4876     sbb     ebp,ebp                     // get -1 if carry
4877     mov     [edi+28],ax                  // store pixel 3
4878
4879     add     ebx,edx                     // increment u fraction
4880     mov     al,[esi]                    // get texture pixel 4
4881     mov         ah, bh
4882     mov         ax, gr_fade_table16[eax*2]
4883
4884
4885     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4886     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4887
4888     sbb     ebp,ebp                     // get -1 if carry
4889     mov     [edi+30],ax                  // store pixel 3
4890
4891     add     ebx,edx                     // increment u fraction
4892     mov     al,[esi]                    // get texture pixel 4
4893     mov         ah, bh
4894     mov         ax, gr_fade_table16[eax*2]
4895
4896
4897     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4898     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4899
4900     sbb     ebp,ebp                     // get -1 if carry
4901     mov     [edi+32],ax                  // store pixel 3
4902
4903     add     ebx,edx                     // increment u fraction
4904     mov     al,[esi]                    // get texture pixel 4
4905     mov         ah, bh
4906     mov         ax, gr_fade_table16[eax*2]
4907
4908
4909     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4910     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4911
4912     sbb     ebp,ebp                     // get -1 if carry
4913     mov     [edi+34],ax                  // store pixel 3
4914
4915     add     ebx,edx                     // increment u fraction
4916     mov     al,[esi]                    // get texture pixel 4
4917     mov         ah, bh
4918     mov         ax, gr_fade_table16[eax*2]
4919
4920
4921     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4922     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4923
4924     sbb     ebp,ebp                     // get -1 if carry
4925     mov     [edi+36],ax                  // store pixel 3
4926
4927     add     ebx,edx                     // increment u fraction
4928     mov     al,[esi]                    // get texture pixel 4
4929     mov         ah, bh
4930     mov         ax, gr_fade_table16[eax*2]
4931
4932
4933     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4934     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4935
4936     sbb     ebp,ebp                     // get -1 if carry
4937     mov     [edi+38],ax                  // store pixel 3
4938
4939     add     ebx,edx                     // increment u fraction
4940     mov     al,[esi]                    // get texture pixel 4
4941     mov         ah, bh
4942     mov         ax, gr_fade_table16[eax*2]
4943
4944
4945     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4946     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4947
4948     sbb     ebp,ebp                     // get -1 if carry
4949     mov     [edi+40],ax                  // store pixel 3
4950
4951     add     ebx,edx                     // increment u fraction
4952     mov     al,[esi]                    // get texture pixel 4
4953     mov         ah, bh
4954     mov         ax, gr_fade_table16[eax*2]
4955
4956
4957     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4958     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4959
4960     sbb     ebp,ebp                     // get -1 if carry
4961     mov     [edi+42],ax                  // store pixel 3
4962
4963     add     ebx,edx                     // increment u fraction
4964     mov     al,[esi]                    // get texture pixel 4
4965     mov         ah, bh
4966     mov         ax, gr_fade_table16[eax*2]
4967
4968
4969     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4970     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4971
4972     sbb     ebp,ebp                     // get -1 if carry
4973     mov     [edi+44],ax                  // store pixel 3
4974
4975     add     ebx,edx                     // increment u fraction
4976     mov     al,[esi]                    // get texture pixel 4
4977     mov         ah, bh
4978     mov         ax, gr_fade_table16[eax*2]
4979
4980
4981     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4982     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4983
4984     sbb     ebp,ebp                     // get -1 if carry
4985     mov     [edi+46],ax                  // store pixel 3
4986
4987     add     ebx,edx                     // increment u fraction
4988     mov     al,[esi]                    // get texture pixel 4
4989     mov         ah, bh
4990     mov         ax, gr_fade_table16[eax*2]
4991
4992
4993     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
4994     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
4995
4996     sbb     ebp,ebp                     // get -1 if carry
4997     mov     [edi+48],ax                  // store pixel 3
4998
4999     add     ebx,edx                     // increment u fraction
5000     mov     al,[esi]                    // get texture pixel 4
5001     mov         ah, bh
5002     mov         ax, gr_fade_table16[eax*2]
5003
5004
5005     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
5006     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
5007
5008     sbb     ebp,ebp                     // get -1 if carry
5009     mov     [edi+50],ax                  // store pixel 3
5010
5011     add     ebx,edx                     // increment u fraction
5012     mov     al,[esi]                    // get texture pixel 4
5013     mov         ah, bh
5014     mov         ax, gr_fade_table16[eax*2]
5015
5016
5017     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
5018     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
5019
5020
5021
5022     sbb     ebp,ebp                     // get -1 if carry
5023     mov     [edi+52],ax                  // store pixel 3
5024
5025     add     ebx,edx                     // increment u fraction
5026     mov     al,[esi]                    // get texture pixel 4
5027     mov         ah, bh
5028     mov         ax, gr_fade_table16[eax*2]
5029
5030
5031     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
5032     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
5033
5034     sbb     ebp,ebp                     // get -1 if carry
5035     mov     [edi+54],ax                  // store pixel 3
5036
5037     add     ebx,edx                     // increment u fraction
5038     mov     al,[esi]                    // get texture pixel 4
5039     mov         ah, bh
5040     mov         ax, gr_fade_table16[eax*2]
5041
5042     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
5043     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
5044
5045     sbb     ebp,ebp                     // get -1 if carry
5046     mov     [edi+56],ax                  // store pixel 4
5047
5048     add     ebx,edx                     // increment u fraction
5049     mov     al,[esi]                    // get texture pixel 5
5050     mov         ah, bh
5051     mov         ax, gr_fade_table16[eax*2]
5052
5053     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
5054     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
5055
5056     sbb     ebp,ebp                     // get -1 if carry
5057     mov     [edi+58],ax                  // store pixel 5
5058
5059     add     ebx,edx                     // increment u fraction
5060     mov     al,[esi]                    // get texture pixel 6
5061     mov         ah, bh
5062     mov         ax, gr_fade_table16[eax*2]
5063
5064     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
5065     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
5066
5067     sbb     ebp,ebp                     // get -1 if carry
5068     mov     [edi+60],ax                  // store pixel 6
5069
5070     add     ebx,edx                     // increment u fraction
5071
5072     mov     al,[esi]                    // get texture pixel 7
5073     mov         ah, bh
5074     mov         ax, gr_fade_table16[eax*2]
5075
5076     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
5077
5078     mov     [edi+62],ax                 // store pixel 7
5079
5080
5081     
5082     ; ************** Okay to Access Stack Frame ****************
5083     ; ************** Okay to Access Stack Frame ****************
5084     ; ************** Okay to Access Stack Frame ****************
5085
5086
5087     ; the fdiv is done, finish right    ; st0  st1  st2  st3  st4  st5  st6  st7
5088                                         ; ZR   V/ZR 1/ZR U/ZR UL   VL
5089
5090     fld     st                          ; ZR   ZR   V/ZR 1/ZR U/ZR UL   VL
5091     fmul    st,st(2)                    ; VR   ZR   V/ZR 1/ZR U/ZR UL   VL
5092     fxch    st(1)                       ; ZR   VR   V/ZR 1/ZR U/ZR UL   VL
5093     fmul    st,st(4)                    ; UR   VR   V/ZR 1/ZR U/ZR UL   VL
5094
5095     add     edi,64                       ; increment to next span
5096     dec     Tmap1.Subdivisions              ; decrement span count
5097     jnz     SpanLoop                    ; loop back
5098
5099         // save new lighting values
5100 //      xor     eax, eax
5101 //      mov     ax, bx
5102 //      mov     Tmap1.fx_l, eax
5103
5104 //      xor     eax, eax
5105 //      mov     ax, dx
5106 //      mov     Tmap1.fx_dl_dx, eax
5107
5108 HandleLeftoverPixels:
5109 //      jmp     FPUReturn
5110
5111     mov     esi,Tmap1.pixptr          ; load texture pointer
5112
5113     ; edi = dest dib bits
5114     ; esi = current texture dib bits
5115     ; at this point the FPU contains    ; st0  st1  st2  st3  st4  st5  st6  st7
5116     ; inv. means invalid numbers        ; inv. inv. inv. inv. inv. UL   VL
5117
5118     cmp     Tmap1.WidthModLength,0          ; are there remaining pixels to draw?
5119     jz      FPUReturn                   ; nope, pop the FPU and bail
5120
5121     ; convert left side coords          ; st0  st1  st2  st3  st4  st5  st6  st7
5122
5123     fld     st(5)                       ; UL   inv. inv. inv. inv. inv. UL   VL
5124     fmul    Tmap1.FixedScale                ; UL16 inv. inv. inv. inv. inv. UL   VL
5125     fistp   Tmap1.UFixed                    ; inv. inv. inv. inv. inv. UL   VL
5126
5127     fld     st(6)                       ; VL   inv. inv. inv. inv. inv. UL   VL
5128     fmul    Tmap1.FixedScale                // VL16 inv. inv. inv. inv. inv. UL   VL
5129     fistp   Tmap1.VFixed                    ; inv. inv. inv. inv. inv. UL   VL
5130
5131     dec     Tmap1.WidthModLength            ; calc how many steps to take
5132     jz      OnePixelSpan                ; just one, don't do deltas
5133
5134     ; calculate right edge coordinates  ; st0  st1  st2  st3  st4  st5  st6  st7
5135     ; r -> R+1
5136
5137     ; @todo rearrange things so we don't need these two instructions
5138     fstp    Tmap1.FloatTemp                 ; inv. inv. inv. inv. UL   VL
5139     fstp    Tmap1.FloatTemp                 ; inv. inv. inv. UL   VL
5140
5141     fld     Tmap1.RightVOverZ           ; V/Zr inv. inv. inv. UL   VL
5142     fsub    Tmap1.dVOverZdX             ; V/ZR inv. inv. inv. UL   VL
5143     fld     Tmap1.RightUOverZ           ; U/Zr V/ZR inv. inv. inv. UL   VL
5144     fsub    Tmap1.dUOverZdX             ; U/ZR V/ZR inv. inv. inv. UL   VL
5145     fld     Tmap1.RightOneOverZ              ; 1/Zr U/ZR V/ZR inv. inv. inv. UL   VL
5146     fsub    Tmap1.dOneOverZdX           ; 1/ZR U/ZR V/ZR inv. inv. inv. UL   VL
5147
5148     fdivr   Tmap1.One                       ; ZR   U/ZR V/ZR inv. inv. inv. UL   VL
5149
5150     fmul    st(1),st                    ; ZR   UR   V/ZR inv. inv. inv. UL   VL
5151     fmulp   st(2),st                    ; UR   VR   inv. inv. inv. UL   VL
5152
5153     ; calculate deltas                  ; st0  st1  st2  st3  st4  st5  st6  st7
5154
5155     fsubr   st(5),st                    ; UR   VR   inv. inv. inv. dU   VL
5156     fxch    st(1)                       ; VR   UR   inv. inv. inv. dU   VL
5157     fsubr   st(6),st                    ; VR   UR   inv. inv. inv. dU   dV
5158     fxch    st(6)                       ; dV   UR   inv. inv. inv. dU   VR
5159
5160     fidiv   Tmap1.WidthModLength            ; dv   UR   inv. inv. inv. dU   VR
5161     fmul    Tmap1.FixedScale                ; dv16 UR   inv. inv. inv. dU   VR
5162     fistp   Tmap1.DeltaV                    ; UR   inv. inv. inv. dU   VR
5163
5164     fxch    st(4)                       ; dU   inv. inv. inv. UR   VR
5165     fidiv   Tmap1.WidthModLength            ; du   inv. inv. inv. UR   VR
5166     fmul    Tmap1.FixedScale                ; du16 inv. inv. inv. UR   VR
5167     fistp   Tmap1.DeltaU                    ; inv. inv. inv. UR   VR
5168
5169     ; @todo gross!  these are to line up with the other loop
5170     fld     st(1)                       ; inv. inv. inv. inv. UR   VR
5171     fld     st(2)                       ; inv. inv. inv. inv. inv. UR   VR
5172
5173 //jmp OldWay
5174
5175
5176         ; setup delta values
5177         mov     eax, Tmap1.DeltaV       // get v 16.16 step
5178         mov     ebx, eax                                                // copy it
5179         sar     eax, 16                                         // get v int step
5180         shl     ebx, 16                                         // get v frac step
5181         mov     Tmap1.DeltaVFrac, ebx   // store it
5182         imul    eax, Tmap1.src_offset   // calc texture step for v int step
5183         
5184         mov     ebx, Tmap1.DeltaU                       // get u 16.16 step
5185         mov     ecx, ebx                                                // copy it
5186         sar     ebx, 16                                         // get the u int step
5187         shl     ecx, 16                                         // get the u frac step
5188         mov     Tmap1.DeltaUFrac, ecx                   // store it
5189         add     eax, ebx                                                // calc uint + vint step
5190         mov     Tmap1.UVintVfracStepVNoCarry, eax       // save whole step in non-v-carry slot
5191         add     eax, Tmap1.src_offset                           // calc whole step + v carry
5192         mov     Tmap1.UVintVfracStepVCarry, eax // save in v-carry slot
5193
5194
5195
5196 OnePixelSpan:
5197
5198 /*
5199 ; check coordinate ranges
5200         mov     eax, Tmap1.UFixed
5201         cmp     eax, Tmap1.MinUFixed
5202         jge     UNotTooSmall_2
5203         mov     eax, Tmap1.MinUFixed
5204         mov     Tmap1.UFixed, eax
5205         jmp     CheckV_2
5206 UNotTooSmall_2: 
5207         cmp     eax, Tmap1.MaxUFixed
5208         jle     CheckV_2
5209         mov     eax, Tmap1.MaxUFixed
5210         mov     Tmap1.UFixed, eax
5211 CheckV_2:
5212         mov     eax, Tmap1.VFixed
5213         cmp     eax, Tmap1.MinVFixed
5214         jge     VNotTooSmall_2
5215         mov     eax, Tmap1.MinVFixed
5216         mov     Tmap1.VFixed, eax
5217         jmp     DoneCheck_2
5218 VNotTooSmall_2: 
5219         cmp     eax, Tmap1.MaxVFixed
5220         jle     DoneCheck_2
5221         mov     eax, Tmap1.MaxVFixed
5222         mov     Tmap1.VFixed, eax
5223 DoneCheck_2:
5224 */
5225
5226
5227
5228
5229         ; setup initial coordinates
5230         mov     esi, Tmap1.UFixed                       // get u 16.16
5231         mov     ebx, esi                                                // copy it
5232         sar     esi, 16                                         // get integer part
5233         shl     ebx, 16                                         // get fractional part
5234
5235         mov     ecx, Tmap1.VFixed                       // get v 16.16 
5236         mov     edx, ecx                                                // copy it
5237         sar     edx, 16                                         // get integer part
5238         shl     ecx, 16                                         // get fractional part
5239         imul    edx, Tmap1.src_offset           // calc texture scanline address
5240         add     esi, edx                                                        // calc texture offset
5241         add     esi, Tmap1.pixptr                       // calc address
5242         
5243         ; set edi = address of first pixel to modify
5244 ;       mov     edi, Tmap1.dest_row_data
5245
5246
5247
5248
5249         mov     eax, Tmap1.fx_l
5250         shr     eax, 8
5251         mov     bx, ax
5252
5253         mov     edx, Tmap1.DeltaUFrac
5254
5255         cmp     Tmap1.WidthModLength, 1
5256         jle     NoDeltaLight
5257
5258         push    ebx
5259         
5260         mov     ebx, Tmap1.fx_l_right
5261         shr     ebx, 8
5262         
5263         sub     ebx, eax
5264         mov     eax, ebx
5265         
5266 #if 0
5267         // slow but maybe better
5268         push    edx
5269         cdq
5270         mov     ebx, Tmap1.WidthModLength 
5271         dec     ebx
5272         idiv    ebx
5273         pop     edx
5274 #else
5275         mov     eax, Tmap1.fx_dl_dx
5276         shr     eax, 8
5277 #endif
5278
5279         mov     dx, ax
5280
5281         pop     ebx
5282
5283 NoDeltaLight:
5284
5285         inc     Tmap1.WidthModLength
5286         mov     eax,Tmap1.WidthModLength
5287         shr     eax, 1
5288         jz              one_more_pix
5289         pushf
5290         mov     Tmap1.WidthModLength, eax
5291
5292         xor     eax, eax
5293
5294     mov     al,[edi]                    // preread the destination cache line
5295
5296 NextPixel:
5297     mov     al,[esi]                    // get texture pixel 0
5298     mov         ah, bh
5299     mov         ax, gr_fade_table16[eax*2]
5300
5301     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
5302     sbb     ebp,ebp                     // get -1 if carry
5303     add     ebx,edx                     // increment u fraction
5304     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
5305     mov     [edi+0],ax                  // store pixel 0
5306
5307     add     ecx,Tmap1.DeltaVFrac        // increment v fraction
5308     sbb     ebp,ebp                     // get -1 if carry
5309     add     ebx,edx                     // increment u fraction
5310     mov     al,[esi]                    // get texture pixel 1
5311     mov         ah, bh
5312     mov         ax, gr_fade_table16[eax*2]
5313
5314     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
5315     mov     [edi+2],ax                  // store pixel 1
5316
5317         add     edi, 4
5318         dec     Tmap1.WidthModLength
5319         jg              NextPixel
5320
5321         popf
5322         jnc     FPUReturn
5323
5324 one_more_pix:   
5325
5326     mov     al,[esi]                    // get texture pixel 2
5327     mov         ah, bh
5328     mov         ax, gr_fade_table16[eax*2]
5329     mov     [edi],ax                  // store pixel 2
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343 /* 
5344 OldWay:         // This is 6% slower than above
5345
5346     mov     ebx,Tmap1.UFixed                ; get starting coordinates
5347     mov     ecx,Tmap1.VFixed                ; for span
5348  
5349     ; leftover pixels loop
5350     ; edi = dest dib bits
5351     ; esi = texture dib bits
5352
5353     ; ebx = u 16.16
5354     ; ecx = v 16.16
5355
5356
5357     mov     eax,ecx                     ; copy v
5358     sar     eax,16                      ; int(v)
5359     imul    eax,Tmap1.src_offset      ; scan offset
5360     mov     edx,ebx                     ; copy u
5361     sar     edx,16                      ; int(u)
5362     add     eax,edx                     ; texture offset
5363     mov     al,[esi+eax]                ; get source pixel
5364 mov al, 0
5365     mov     [edi],al                    ; store it
5366     inc     edi
5367     add     ebx,Tmap1.DeltaU                  ; increment u coordinate
5368     add     ecx,Tmap1.DeltaV                  ; increment v coordinate
5369
5370     dec     Tmap1.WidthModLength            ; decrement loop count
5371     jl     FPUReturn                ; finish up
5372          
5373
5374 LeftoverLoop:
5375     mov     eax,ecx                     ; copy v
5376     sar     eax,16                      ; int(v)
5377     imul    eax,Tmap1.src_offset      ; scan offset
5378     mov     edx,ebx                     ; copy u
5379     sar     edx,16                      ; int(u)
5380     add     eax,edx                     ; texture offset
5381     mov     al,[esi+eax]                ; get source pixel
5382     mov     [edi],al                    ; store it
5383     inc     edi
5384     add     ebx,Tmap1.DeltaU                  ; increment u coordinate
5385     add     ecx,Tmap1.DeltaV                  ; increment v coordinate
5386
5387     dec     Tmap1.WidthModLength            ; decrement loop count
5388     jge     LeftoverLoop                ; finish up
5389 */
5390
5391 FPUReturn:
5392
5393     ; busy FPU registers:               ; st0  st1  st2  st3  st4  st5  st6  st7
5394                                         ; xxx  xxx  xxx  xxx  xxx  xxx  xxx
5395     ffree   st(0)
5396     ffree   st(1)
5397     ffree   st(2)
5398     ffree   st(3)
5399     ffree   st(4)
5400     ffree   st(5)
5401     ffree   st(6)
5402
5403 //Return:
5404
5405     fldcw   Tmap1.OldFPUCW                  // restore the FPU
5406
5407         pop     edi
5408         pop     esi
5409         pop     ebp
5410         pop     ebx
5411         pop     edx
5412         pop     ecx
5413         pop     eax
5414         }
5415
5416
5417 }
5418
5419
5420
5421
5422 void tmapscan_lnn16( int lx, int rx, int y, vertex *p, vertex *dp,  vertex * rp,uint flags )
5423 {
5424         Tmap1.dest_row_data = (ubyte *)GR_SCREEN_PTR(ushort,lx,y);
5425         Tmap1.loop_count = rx - lx;
5426         Tmap1.pixptr = (unsigned char *)tmap_bitmap->data;
5427         Tmap1.bp = tmap_bitmap;
5428         Tmap1.src_offset = tmap_bitmap->w;
5429
5430         Tmap1.fx_u = fl2f(p->u);
5431         Tmap1.fx_v = fl2f(p->v);
5432         Tmap1.fx_du_dx = fl2f(dp->u);
5433         Tmap1.fx_dv_dx = fl2f(dp->v);
5434         Tmap1.fx_u_right = fl2f(rp->u);
5435         Tmap1.fx_v_right = fl2f(rp->v);
5436
5437         int end;
5438
5439         end = f2i(Tmap1.fx_u);
5440         if ( end >= Tmap1.bp->w ) return;
5441         
5442         end = f2i(Tmap1.fx_v);
5443         if ( end >= Tmap1.bp->h ) return;
5444
5445         end = f2i(Tmap1.fx_u_right);
5446         if ( end >= Tmap1.bp->w ) return;
5447
5448         end = f2i(Tmap1.fx_v_right);
5449         if ( end >= Tmap1.bp->h ) return;
5450
5451
5452         _asm {
5453         push    eax
5454         push    ecx
5455         push    edx
5456         push    ebx
5457         push    ebp
5458         push    esi
5459         push    edi
5460
5461         ; setup delta values
5462         mov     eax, Tmap1.fx_dv_dx     // get v 16.16 step
5463         mov     ebx, eax                                                // copy it
5464         sar     eax, 16                                         // get v int step
5465         shl     ebx, 16                                         // get v frac step
5466         mov     Tmap1.DeltaVFrac, ebx   // store it
5467         imul    eax, Tmap1.src_offset   // calc texture step for v int step
5468         
5469         mov     ebx, Tmap1.fx_du_dx             // get u 16.16 step
5470         mov     ecx, ebx                                                // copy it
5471         sar     ebx, 16                                         // get the u int step
5472         shl     ecx, 16                                         // get the u frac step
5473         mov     Tmap1.DeltaUFrac, ecx                   // store it
5474         add     eax, ebx                                                // calc uint + vint step
5475         mov     Tmap1.UVintVfracStepVNoCarry, eax       // save whole step in non-v-carry slot
5476         add     eax, Tmap1.src_offset                           // calc whole step + v carry
5477         mov     Tmap1.UVintVfracStepVCarry, eax // save in v-carry slot
5478
5479         ; setup initial coordinates
5480         mov     esi, Tmap1.fx_u                 // get u 16.16
5481         mov     ebx, esi                                                // copy it
5482         sar     esi, 16                                         // get integer part
5483         shl     ebx, 16                                         // get fractional part
5484
5485         mov     ecx, Tmap1.fx_v                 // get v 16.16 
5486         mov     edx, ecx                                                // copy it
5487         sar     edx, 16                                         // get integer part
5488         shl     ecx, 16                                         // get fractional part
5489         imul    edx, Tmap1.src_offset           // calc texture scanline address
5490         add     esi, edx                                                        // calc texture offset
5491         add     esi, Tmap1.pixptr                       // calc address
5492         
5493         ; set edi = address of first pixel to modify
5494         mov     edi, Tmap1.dest_row_data
5495         
5496         mov     edx, Tmap1.DeltaUFrac
5497
5498         mov     eax, Tmap1.loop_count
5499         inc     eax
5500         mov     Tmap1.loop_count, eax
5501
5502         shr     eax, 3
5503         je              DoLeftOverPixels
5504
5505         mov     Tmap1.num_big_steps, eax
5506         and     Tmap1.loop_count, 7
5507
5508         xor     eax, eax
5509
5510 NextPixelBlock:
5511
5512     // 8 pixel span code
5513     // edi = dest dib bits at current pixel
5514     // esi = texture pointer at current u,v
5515     // eax = scratch
5516     // ebx = u fraction 0.32
5517     // ecx = v fraction 0.32
5518     // edx = u frac step
5519     // ebp = v carry scratch
5520
5521     mov     al,[edi]                    // preread the destination cache line
5522
5523     movzx   eax,byte ptr [esi]                    // get texture pixel 0
5524
5525     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
5526     sbb     ebp,ebp                     // get -1 if carry
5527     add     ebx,edx                     // increment u fraction
5528
5529     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
5530     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
5531
5532     sbb     ebp,ebp                     // get -1 if carry
5533          mov            ax, palman_8_16_xlat[eax*2]
5534     mov     [edi+0],ax                  // store pixel 0
5535
5536     add     ebx,edx                     // increment u fraction
5537           movzx   eax,byte ptr [esi]                    // get texture pixel 0
5538
5539     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
5540     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
5541
5542     sbb     ebp,ebp                     // get -1 if carry
5543          mov            ax, palman_8_16_xlat[eax*2]
5544     mov     [edi+2],ax                  // store pixel 0
5545
5546     add     ebx,edx                     // increment u fraction
5547           movzx   eax,byte ptr [esi]                    // get texture pixel 0
5548
5549     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
5550     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
5551
5552     sbb     ebp,ebp                     // get -1 if carry
5553          mov            ax, palman_8_16_xlat[eax*2]
5554     mov     [edi+4],ax                  // store pixel 0
5555
5556     add     ebx,edx                     // increment u fraction
5557           movzx   eax,byte ptr [esi]                    // get texture pixel 0
5558
5559     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
5560     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
5561
5562     sbb     ebp,ebp                     // get -1 if carry
5563          mov            ax, palman_8_16_xlat[eax*2]
5564     mov     [edi+6],ax                  // store pixel 0
5565
5566     add     ebx,edx                     // increment u fraction
5567           movzx   eax,byte ptr [esi]                    // get texture pixel 0
5568
5569     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
5570     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
5571
5572     sbb     ebp,ebp                     // get -1 if carry
5573          mov            ax, palman_8_16_xlat[eax*2]
5574     mov     [edi+8],ax                  // store pixel 0
5575
5576     add     ebx,edx                     // increment u fraction
5577           movzx   eax,byte ptr [esi]                    // get texture pixel 0
5578
5579     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
5580     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
5581
5582     sbb     ebp,ebp                     // get -1 if carry
5583          mov            ax, palman_8_16_xlat[eax*2]
5584     mov     [edi+10],ax                  // store pixel 0
5585
5586     add     ebx,edx                     // increment u fraction
5587           movzx   eax,byte ptr [esi]                    // get texture pixel 0
5588
5589     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
5590     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
5591
5592     sbb     ebp,ebp                     // get -1 if carry
5593          mov            ax, palman_8_16_xlat[eax*2]
5594     mov     [edi+12],ax                  // store pixel 0
5595
5596     add     ebx,edx                     // increment u fraction
5597
5598           movzx   eax,byte ptr [esi]                    // get texture pixel 0
5599
5600     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
5601
5602          mov            ax, palman_8_16_xlat[eax*2]
5603     mov     [edi+14],ax                  // store pixel 0
5604  
5605                 ; end
5606         
5607
5608         add     edi, 16
5609         dec     Tmap1.num_big_steps
5610         jne     NextPixelBlock
5611         
5612
5613 DoLeftOverPixels:
5614
5615         mov     eax,Tmap1.loop_count
5616         test    eax, -1
5617         jz      _none_to_do
5618         shr     eax, 1
5619         je      one_more_pix
5620         mov     Tmap1.loop_count, eax
5621         pushf
5622
5623         xor     eax, eax
5624
5625     mov     al,[edi]                    // preread the destination cache line
5626 //    add     ebx,edx                     // increment u fraction
5627
5628 NextPixel:
5629
5630           movzx   eax,byte ptr [esi]                    // get texture pixel 0
5631
5632     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
5633     sbb     ebp,ebp                     // get -1 if carry
5634     add     ebx,edx                     // increment u fraction
5635     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
5636          mov            ax, palman_8_16_xlat[eax*2]
5637     mov     [edi+0],ax                  // store pixel 0
5638
5639     add     ecx,Tmap1.DeltaVFrac        // increment v fraction
5640     sbb     ebp,ebp                     // get -1 if carry
5641     add     ebx,edx                     // increment u fraction
5642           movzx   eax,byte ptr [esi]                    // get texture pixel 0
5643
5644     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
5645          mov            ax, palman_8_16_xlat[eax*2]
5646     mov     [edi+2],ax                  // store pixel 0
5647
5648         add     edi, 4
5649         dec     Tmap1.loop_count
5650         jne     NextPixel
5651
5652         popf
5653         jnc     _none_to_do
5654
5655 one_more_pix:   
5656
5657           movzx   eax,byte ptr [esi]                    // get texture pixel 0
5658          mov            ax, palman_8_16_xlat[eax*2]
5659     mov     [edi],ax                  // store pixel 0
5660
5661 _none_to_do:    
5662         pop     edi
5663         pop     esi
5664         pop     ebp
5665         pop     ebx
5666         pop     edx
5667         pop     ecx
5668         pop     eax
5669         }
5670 }
5671
5672
5673
5674 void tmapscan_lnn32( int lx, int rx, int y, vertex *p, vertex *dp,  vertex * rp,uint flags )
5675 {
5676         Tmap1.dest_row_data = (ubyte *)GR_SCREEN_PTR(uint,lx,y);
5677         Tmap1.loop_count = rx - lx;
5678         Tmap1.pixptr = (unsigned char *)tmap_bitmap->data;
5679         Tmap1.bp = tmap_bitmap;
5680         Tmap1.src_offset = tmap_bitmap->w;
5681
5682         Tmap1.fx_u = fl2f(p->u);
5683         Tmap1.fx_v = fl2f(p->v);
5684         Tmap1.fx_du_dx = fl2f(dp->u);
5685         Tmap1.fx_dv_dx = fl2f(dp->v);
5686         Tmap1.fx_u_right = fl2f(rp->u);
5687         Tmap1.fx_v_right = fl2f(rp->v);
5688
5689         int end;
5690
5691         end = f2i(Tmap1.fx_u);
5692         if ( end >= Tmap1.bp->w ) return;
5693         
5694         end = f2i(Tmap1.fx_v);
5695         if ( end >= Tmap1.bp->h ) return;
5696
5697         end = f2i(Tmap1.fx_u_right);
5698         if ( end >= Tmap1.bp->w ) return;
5699
5700         end = f2i(Tmap1.fx_v_right);
5701         if ( end >= Tmap1.bp->h ) return;
5702
5703
5704         _asm {
5705         push    eax
5706         push    ecx
5707         push    edx
5708         push    ebx
5709         push    ebp
5710         push    esi
5711         push    edi
5712
5713         ; setup delta values
5714         mov     eax, Tmap1.fx_dv_dx     // get v 16.16 step
5715         mov     ebx, eax                                                // copy it
5716         sar     eax, 16                                         // get v int step
5717         shl     ebx, 16                                         // get v frac step
5718         mov     Tmap1.DeltaVFrac, ebx   // store it
5719         imul    eax, Tmap1.src_offset   // calc texture step for v int step
5720         
5721         mov     ebx, Tmap1.fx_du_dx             // get u 16.16 step
5722         mov     ecx, ebx                                                // copy it
5723         sar     ebx, 16                                         // get the u int step
5724         shl     ecx, 16                                         // get the u frac step
5725         mov     Tmap1.DeltaUFrac, ecx                   // store it
5726         add     eax, ebx                                                // calc uint + vint step
5727         mov     Tmap1.UVintVfracStepVNoCarry, eax       // save whole step in non-v-carry slot
5728         add     eax, Tmap1.src_offset                           // calc whole step + v carry
5729         mov     Tmap1.UVintVfracStepVCarry, eax // save in v-carry slot
5730
5731         ; setup initial coordinates
5732         mov     esi, Tmap1.fx_u                 // get u 16.16
5733         mov     ebx, esi                                                // copy it
5734         sar     esi, 16                                         // get integer part
5735         shl     ebx, 16                                         // get fractional part
5736
5737         mov     ecx, Tmap1.fx_v                 // get v 16.16 
5738         mov     edx, ecx                                                // copy it
5739         sar     edx, 16                                         // get integer part
5740         shl     ecx, 16                                         // get fractional part
5741         imul    edx, Tmap1.src_offset           // calc texture scanline address
5742         add     esi, edx                                                        // calc texture offset
5743         add     esi, Tmap1.pixptr                       // calc address
5744         
5745         ; set edi = address of first pixel to modify
5746         mov     edi, Tmap1.dest_row_data
5747         
5748         mov     edx, Tmap1.DeltaUFrac
5749
5750         mov     eax, Tmap1.loop_count
5751         inc     eax
5752         mov     Tmap1.loop_count, eax
5753
5754         shr     eax, 3
5755         je              DoLeftOverPixels
5756
5757         mov     Tmap1.num_big_steps, eax
5758         and     Tmap1.loop_count, 7
5759
5760         xor     eax, eax
5761
5762 NextPixelBlock:
5763
5764     // 8 pixel span code
5765     // edi = dest dib bits at current pixel
5766     // esi = texture pointer at current u,v
5767     // eax = scratch
5768     // ebx = u fraction 0.32
5769     // ecx = v fraction 0.32
5770     // edx = u frac step
5771     // ebp = v carry scratch
5772
5773     mov     al,[edi]                    // preread the destination cache line
5774
5775     movzx   eax,byte ptr [esi]                    // get texture pixel 0
5776
5777     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
5778     sbb     ebp,ebp                     // get -1 if carry
5779     add     ebx,edx                     // increment u fraction
5780
5781     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
5782     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
5783
5784     sbb     ebp,ebp                     // get -1 if carry
5785          mov            eax, palman_8_32_xlat[eax*4]
5786     mov     [edi+0],eax                  // store pixel 0
5787
5788     add     ebx,edx                     // increment u fraction
5789           movzx   eax,byte ptr [esi]                    // get texture pixel 0
5790
5791     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
5792     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
5793
5794     sbb     ebp,ebp                     // get -1 if carry
5795          mov            eax, palman_8_32_xlat[eax*4]
5796     mov     [edi+4],eax                  // store pixel 0
5797
5798     add     ebx,edx                     // increment u fraction
5799           movzx   eax,byte ptr [esi]                    // get texture pixel 0
5800
5801     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
5802     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
5803
5804     sbb     ebp,ebp                     // get -1 if carry
5805          mov            eax, palman_8_32_xlat[eax*4]
5806     mov     [edi+8],eax                  // store pixel 0
5807
5808     add     ebx,edx                     // increment u fraction
5809           movzx   eax,byte ptr [esi]                    // get texture pixel 0
5810
5811     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
5812     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
5813
5814     sbb     ebp,ebp                     // get -1 if carry
5815          mov            eax, palman_8_32_xlat[eax*4]
5816     mov     [edi+12],eax                  // store pixel 0
5817
5818     add     ebx,edx                     // increment u fraction
5819           movzx   eax,byte ptr [esi]                    // get texture pixel 0
5820
5821     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
5822     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
5823
5824     sbb     ebp,ebp                     // get -1 if carry
5825          mov            eax, palman_8_32_xlat[eax*4]
5826     mov     [edi+16],eax                  // store pixel 0
5827
5828     add     ebx,edx                     // increment u fraction
5829           movzx   eax,byte ptr [esi]                    // get texture pixel 0
5830
5831     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
5832     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
5833
5834     sbb     ebp,ebp                     // get -1 if carry
5835          mov            eax, palman_8_32_xlat[eax*4]
5836     mov     [edi+20],eax                  // store pixel 0
5837
5838     add     ebx,edx                     // increment u fraction
5839           movzx   eax,byte ptr [esi]                    // get texture pixel 0
5840
5841     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
5842     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
5843
5844     sbb     ebp,ebp                     // get -1 if carry
5845          mov            eax, palman_8_32_xlat[eax*4]
5846     mov     [edi+24],eax                  // store pixel 0
5847
5848     add     ebx,edx                     // increment u fraction
5849
5850           movzx   eax,byte ptr [esi]                    // get texture pixel 0
5851
5852     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
5853
5854          mov            eax, palman_8_32_xlat[eax*4]
5855     mov     [edi+28],eax                  // store pixel 0
5856  
5857                 ; end
5858         
5859
5860         add     edi, 32
5861         dec     Tmap1.num_big_steps
5862         jne     NextPixelBlock
5863         
5864
5865 DoLeftOverPixels:
5866
5867         mov     eax,Tmap1.loop_count
5868         test    eax, -1
5869         jz      _none_to_do
5870         shr     eax, 1
5871         je      one_more_pix
5872         mov     Tmap1.loop_count, eax
5873         pushf
5874
5875         xor     eax, eax
5876
5877     mov     al,[edi]                    // preread the destination cache line
5878 //    add     ebx,edx                     // increment u fraction
5879
5880 NextPixel:
5881
5882           movzx   eax,byte ptr [esi]                    // get texture pixel 0
5883
5884     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
5885     sbb     ebp,ebp                     // get -1 if carry
5886     add     ebx,edx                     // increment u fraction
5887     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
5888          mov            eax, palman_8_32_xlat[eax*4]
5889     mov     [edi+0],eax                  // store pixel 0
5890
5891     add     ecx,Tmap1.DeltaVFrac        // increment v fraction
5892     sbb     ebp,ebp                     // get -1 if carry
5893     add     ebx,edx                     // increment u fraction
5894           movzx   eax,byte ptr [esi]                    // get texture pixel 0
5895
5896     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
5897          mov            eax, palman_8_32_xlat[eax*4]
5898     mov     [edi+4],eax                  // store pixel 0
5899
5900         add     edi, 8
5901         dec     Tmap1.loop_count
5902         jne     NextPixel
5903
5904         popf
5905         jnc     _none_to_do
5906
5907 one_more_pix:   
5908
5909           movzx   eax,byte ptr [esi]                    // get texture pixel 0
5910          mov            eax, palman_8_32_xlat[eax*4]
5911     mov     [edi],eax                  // store pixel 0
5912
5913 _none_to_do:    
5914         pop     edi
5915         pop     esi
5916         pop     ebp
5917         pop     ebx
5918         pop     edx
5919         pop     ecx
5920         pop     eax
5921         }
5922 }
5923
5924
5925 void tmapscan_pln32( int lx, int rx, int y, vertex *p, vertex *dp,  vertex * rp,uint flags )
5926 {
5927         Tmap1.dest_row_data = (ubyte *)GR_SCREEN_PTR(uint,lx,y);
5928         Tmap1.loop_count = rx - lx;
5929         Tmap1.fx_u = fl2f(p->u);
5930         Tmap1.fx_v = fl2f(p->v);
5931         Tmap1.fx_du_dx = fl2f(dp->u);
5932         Tmap1.fx_dv_dx = fl2f(dp->v);
5933
5934         Tmap1.fx_l = fl2f(p->l*32.0); 
5935         Tmap1.fx_dl_dx = fl2f(dp->l*32.0);
5936
5937         Tmap1.fx_u_right = fl2f(rp->u);
5938         Tmap1.fx_v_right = fl2f(rp->v);
5939         Tmap1.pixptr = (unsigned char *)tmap_bitmap->data;
5940         Tmap1.bp = tmap_bitmap;
5941         Tmap1.src_offset = tmap_bitmap->w;
5942
5943
5944         Tmap1.FixedScale = 65536.0f;
5945         Tmap1.FixedScale8 =     2048.0f;        //8192.0f;      // 2^16 / 8
5946         Tmap1.One = 1.0f;
5947
5948
5949    Tmap1.UOverZ = p->u;
5950         Tmap1.VOverZ = p->v;
5951         Tmap1.OneOverZ = p->sw;
5952
5953         Tmap1.dUOverZdX8 = dp->u*32.0f;
5954         Tmap1.dVOverZdX8 = dp->v*32.0f;
5955         Tmap1.dOneOverZdX8 = dp->sw*32.0f;
5956
5957         Tmap1.dUOverZdX = dp->u;
5958         Tmap1.dVOverZdX = dp->v;
5959         Tmap1.dOneOverZdX = dp->sw;
5960
5961    Tmap1.RightUOverZ = rp->u;
5962         Tmap1.RightVOverZ = rp->v;
5963         Tmap1.RightOneOverZ = rp->sw;
5964
5965
5966         Tmap1.BitmapWidth = Tmap1.bp->w;
5967         Tmap1.BitmapHeight = Tmap1.bp->h;
5968
5969
5970         if ( Tmap1.fx_dl_dx < 0 )       {
5971                 Tmap1.fx_dl_dx = -Tmap1.fx_dl_dx;
5972                 Tmap1.fx_l = (67*F1_0)-Tmap1.fx_l;
5973                 Tmap1.fx_l_right = (67*F1_0)-Tmap1.fx_l_right;
5974 //              return;
5975 //              Assert( Tmap1.fx_l > 31*F1_0 );
5976 //              Assert( Tmap1.fx_l < 66*F1_0 );
5977 //              Assert( Tmap1.fx_dl_dx >= 0 );
5978 //              Assert( Tmap1.fx_dl_dx < 31*F1_0 );
5979         }
5980
5981 //      return;
5982
5983
5984
5985         _asm {
5986         
5987         push    eax
5988         push    ecx
5989         push    edx
5990         push    ebx
5991         push    ebp
5992         push    esi
5993         push    edi
5994
5995
5996         // put the FPU in 32 bit mode
5997         // @todo move this out of here!
5998
5999         fstcw           Tmap1.OldFPUCW                                  // store copy of CW
6000         mov             ax,Tmap1.OldFPUCW                               // get it in ax
6001 //hh    and             eax,NOT 1100000000y                     // 24 bit precision
6002         and             eax, ~0x300L
6003         mov             Tmap1.FPUCW,ax                                  // store it
6004         fldcw           Tmap1.FPUCW                                             // load the FPU
6005
6006         mov             ecx, Tmap1.loop_count           // ecx = width
6007         inc             ecx
6008         mov             edi, Tmap1.dest_row_data        // edi = dest pointer
6009
6010         // edi = pointer to start pixel in dest dib
6011         // ecx = spanwidth
6012
6013         mov             eax,ecx                                                 // eax and ecx = width
6014         shr             ecx,5                                                           // ecx = width / subdivision length
6015         and             eax,31                                                          // eax = width mod subdivision length
6016         jnz             some_left_over                                  // any leftover?
6017 //      jmp             Return
6018         dec             ecx                                                             // no, so special case last span
6019         mov             eax,32                                                          // it's 8 pixels long
6020 some_left_over:
6021         mov             Tmap1.Subdivisions,ecx          // store widths
6022         mov             Tmap1.WidthModLength,eax
6023     
6024 //    mov     ebx,pLeft                   ; get left edge pointer
6025 //    mov     edx,pGradients              ; get gradients pointer
6026
6027         // calculate ULeft and VLeft                    // FPU Stack (ZL = ZLeft)
6028                                                                                                         // st0  st1  st2  st3  st4  st5  st6  st7
6029         fld             Tmap1.VOverZ                                    // V/ZL 
6030         fld             Tmap1.UOverZ                                    // U/ZL V/ZL 
6031         fld             Tmap1.OneOverZ                                  // 1/ZL U/ZL V/ZL 
6032         fld1                                                                                    // 1    1/ZL U/ZL V/ZL 
6033         fdiv            st,st(1)                                                        // ZL   1/ZL U/ZL V/ZL 
6034         fld             st                                                                      // ZL   ZL   1/ZL U/ZL V/ZL 
6035         fmul            st,st(4)                                                        // VL   ZL   1/ZL U/ZL V/ZL 
6036         fxch            st(1)                                                           // ZL   VL   1/ZL U/ZL V/ZL 
6037         fmul            st,st(3)                                                        // UL   VL   1/ZL U/ZL V/ZL 
6038
6039         fstp            st(5)                                                           // VL   1/ZL U/ZL V/ZL UL
6040         fstp            st(5)                                                           // 1/ZL U/ZL V/ZL UL   VL
6041
6042         // calculate right side OverZ terms  ; st0  st1  st2  st3  st4  st5  st6  st7
6043
6044         fadd            Tmap1.dOneOverZdX8                      // 1/ZR U/ZL V/ZL UL   VL
6045         fxch            st(1)                                                           // U/ZL 1/ZR V/ZL UL   VL
6046         fadd            Tmap1.dUOverZdX8                                // U/ZR 1/ZR V/ZL UL   VL
6047         fxch            st(2)                                                           // V/ZL 1/ZR U/ZR UL   VL
6048         fadd            Tmap1.dVOverZdX8                                // V/ZR 1/ZR U/ZR UL   VL
6049
6050         // calculate right side coords          // st0  st1  st2  st3  st4  st5  st6  st7
6051
6052         fld1                                                                                    // 1    V/ZR 1/ZR U/ZR UL   VL
6053         // @todo overlap this guy
6054         fdiv            st,st(2)                                                        // ZR   V/ZR 1/ZR U/ZR UL   VL
6055         fld             st                                                                      // ZR   ZR   V/ZR 1/ZR U/ZR UL   VL
6056         fmul            st,st(2)                                                        // VR   ZR   V/ZR 1/ZR U/ZR UL   VL
6057         fxch            st(1)                                                           // ZR   VR   V/ZR 1/ZR U/ZR UL   VL
6058         fmul            st,st(4)                                                        // UR   VR   V/ZR 1/ZR U/ZR UL   VL
6059
6060         cmp             ecx,0                                                   // check for any full spans
6061         jle      HandleLeftoverPixels
6062     
6063 SpanLoop:
6064
6065         // at this point the FPU contains       // st0  st1  st2  st3  st4  st5  st6  st7
6066                                                                                                         // UR   VR   V/ZR 1/ZR U/ZR UL   VL
6067
6068         // convert left side coords
6069
6070         fld     st(5)                       ; UL   UR   VR   V/ZR 1/ZR U/ZR UL   VL
6071         fmul    Tmap1.FixedScale            ; UL16 UR   VR   V/ZR 1/ZR U/ZR UL   VL
6072         fistp   Tmap1.UFixed                ; UR   VR   V/ZR 1/ZR U/ZR UL   VL
6073
6074         fld     st(6)                       ; VL   UR   VR   V/ZR 1/ZR U/ZR UL   VL
6075         fmul    Tmap1.FixedScale            ; VL16 UR   VR   V/ZR 1/ZR U/ZR UL   VL
6076         fistp   Tmap1.VFixed                ; UR   VR   V/ZR 1/ZR U/ZR UL   VL
6077
6078         // calculate deltas                  ; st0  st1  st2  st3  st4  st5  st6  st7
6079
6080         fsubr   st(5),st                    ; UR   VR   V/ZR 1/ZR U/ZR dU   VL
6081         fxch    st(1)                       ; VR   UR   V/ZR 1/ZR U/ZR dU   VL
6082         fsubr   st(6),st                    ; VR   UR   V/ZR 1/ZR U/ZR dU   dV
6083         fxch    st(6)                       ; dV   UR   V/ZR 1/ZR U/ZR dU   VR
6084
6085         fmul    Tmap1.FixedScale8           ; dV8  UR   V/ZR 1/ZR U/ZR dU   VR
6086         fistp   Tmap1.DeltaV                ; UR   V/ZR 1/ZR U/ZR dU   VR
6087
6088         fxch    st(4)                       ; dU   V/ZR 1/ZR U/ZR UR   VR
6089         fmul    Tmap1.FixedScale8           ; dU8  V/ZR 1/ZR U/ZR UR   VR
6090         fistp   Tmap1.DeltaU                ; V/ZR 1/ZR U/ZR UR   VR
6091
6092         // increment terms for next span     ; st0  st1  st2  st3  st4  st5  st6  st7
6093         // Right terms become Left terms---->; V/ZL 1/ZL U/ZL UL   VL
6094
6095         fadd    Tmap1.dVOverZdX8            ; V/ZR 1/ZL U/ZL UL   VL
6096         fxch    st(1)                       ; 1/ZL V/ZR U/ZL UL   VL
6097         fadd    Tmap1.dOneOverZdX8          ; 1/ZR V/ZR U/ZL UL   VL
6098         fxch    st(2)                       ; U/ZL V/ZR 1/ZR UL   VL
6099         fadd    Tmap1.dUOverZdX8            ; U/ZR V/ZR 1/ZR UL   VL
6100         fxch    st(2)                       ; 1/ZR V/ZR U/ZR UL   VL
6101         fxch    st(1)                       ; V/ZR 1/ZR U/ZR UL   VL
6102
6103         ; calculate right side coords       ; st0  st1  st2  st3  st4  st5  st6  st7
6104
6105         fld1                                ; 1    V/ZR 1/ZR U/ZR UL   VL
6106         fdiv    st,st(2)                    ; ZR   V/ZR 1/ZR U/ZR UL   VL
6107
6108
6109     ; set up affine registers
6110
6111     ; setup delta values
6112     
6113     mov     eax,Tmap1.DeltaV                ; get v 16.16 step
6114     mov     ebx,eax                     ; copy it
6115     sar     eax,16                      ; get v int step
6116     shl     ebx,16                      ; get v frac step
6117     mov     Tmap1.DeltaVFrac,ebx            ; store it
6118     imul    eax,Tmap1.src_offset      ; calculate texture step for v int step
6119
6120     mov     ebx,Tmap1.DeltaU                ; get u 16.16 step
6121     mov     ecx,ebx                     ; copy it
6122     sar     ebx,16                      ; get u int step
6123     shl     ecx,16                      ; get u frac step
6124     mov     Tmap1.DeltaUFrac,ecx            ; store it
6125     add     eax,ebx                     ; calculate uint + vint step
6126     mov     Tmap1.UVintVfracStepVNoCarry,eax; save whole step in non-v-carry slot
6127     add     eax,Tmap1.src_offset      ; calculate whole step + v carry
6128     mov     Tmap1.UVintVfracStepVCarry,eax  ; save in v-carry slot
6129
6130
6131 /*
6132 ; check coordinate ranges
6133         mov     eax, Tmap1.UFixed
6134         cmp     eax, Tmap1.MinUFixed
6135         jge     UNotTooSmall_1
6136         mov     eax, Tmap1.MinUFixed
6137         mov     Tmap1.UFixed, eax
6138         jmp     CheckV_1
6139 UNotTooSmall_1: 
6140         cmp     eax, Tmap1.MaxUFixed
6141         jle     CheckV_1
6142         mov     eax, Tmap1.MaxUFixed
6143         mov     Tmap1.UFixed, eax
6144 CheckV_1:
6145         mov     eax, Tmap1.VFixed
6146         cmp     eax, Tmap1.MinVFixed
6147         jge     VNotTooSmall_1
6148         mov     eax, Tmap1.MinVFixed
6149         mov     Tmap1.VFixed, eax
6150         jmp     DoneCheck_1
6151 VNotTooSmall_1: 
6152         cmp     eax, Tmap1.MaxVFixed
6153         jle     DoneCheck_1
6154         mov     eax, Tmap1.MaxVFixed
6155         mov     Tmap1.VFixed, eax
6156 DoneCheck_1:
6157 */
6158     
6159 ; setup initial coordinates
6160     mov     esi,Tmap1.UFixed                ; get u 16.16 fixedpoint coordinate
6161    
6162     mov     ebx,esi                     ; copy it
6163     sar     esi,16                      ; get integer part
6164     shl     ebx,16                      ; get fractional part
6165     
6166     mov     ecx,Tmap1.VFixed                ; get v 16.16 fixedpoint coordinate
6167    
6168     mov     edx,ecx                     ; copy it
6169     sar     edx,16                      ; get integer part
6170     shl     ecx,16                      ; get fractional part
6171     imul    edx,Tmap1.src_offset      ; calc texture scanline address
6172     add     esi,edx                     ; calc texture offset
6173     add     esi,Tmap1.pixptr          ; calc address
6174
6175     mov     edx,Tmap1.DeltaUFrac            ; get register copy
6176
6177         mov     eax, Tmap1.fx_l
6178         shr     eax, 8
6179         mov     bx, ax
6180
6181         mov     ebp, Tmap1.fx_dl_dx
6182         shl     ebp, 5  //*32
6183         add     Tmap1.fx_l, ebp
6184
6185         mov     ebp, Tmap1.fx_l
6186         shr     ebp, 8
6187         sub     bp, ax
6188         shr     bp, 5
6189
6190         mov     dx, bp
6191
6192 //      add     Tmap1.fx_l, eax
6193
6194
6195 //      mov     eax, Tmap1.fx_l // use bx and dx to do lighting
6196 //mov eax, 31*256
6197 //      mov     bx, ax
6198 //      mov     eax, Tmap1.fx_dl_dx     // use bx and dx to do lighting
6199 //mov eax, 0
6200 //      mov     dx, ax
6201
6202
6203
6204     ; ************** Can't Access Stack Frame ******************
6205     ; ************** Can't Access Stack Frame ******************
6206     ; ************** Can't Access Stack Frame ******************
6207
6208     // 8 pixel span code
6209     // edi = dest dib bits at current pixel
6210     // esi = texture pointer at current u,v
6211     // eax = scratch
6212     // ebx = u fraction 0.32
6213     // ecx = v fraction 0.32
6214     // edx = u frac step
6215     // ebp = v carry scratch
6216
6217     mov     al,[edi]                    // preread the destination cache line
6218
6219
6220     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6221     mov         ah, bh
6222     mov         eax, gr_fade_table32[eax*4]
6223
6224     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
6225     sbb     ebp,ebp                     // get -1 if carry
6226     add     ebx,edx                     // increment u fraction
6227
6228     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
6229     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
6230
6231     sbb     ebp,ebp                     // get -1 if carry
6232 //      mov al, 0       // Uncomment this line to show divisions
6233     mov     [edi+0],eax                  // store pixel 0
6234
6235     add     ebx,edx                     // increment u fraction
6236     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6237     mov         ah, bh
6238     mov         eax, gr_fade_table32[eax*4]
6239
6240     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
6241     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
6242
6243     sbb     ebp,ebp                     // get -1 if carry
6244     mov     [edi+4],eax                  // store pixel 1
6245
6246     add     ebx,edx                     // increment u fraction
6247     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6248     mov         ah, bh
6249     mov         eax, gr_fade_table32[eax*4]
6250
6251     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
6252     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
6253
6254     sbb     ebp,ebp                     // get -1 if carry
6255     mov     [edi+8],eax                  // store pixel 2
6256
6257     add     ebx,edx                     // increment u fraction
6258     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6259     mov         ah, bh
6260     mov         eax, gr_fade_table32[eax*4]
6261
6262     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
6263     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
6264
6265     sbb     ebp,ebp                     // get -1 if carry
6266     mov     [edi+12],eax                  // store pixel 3
6267
6268     add     ebx,edx                     // increment u fraction
6269     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6270     mov         ah, bh
6271     mov         eax, gr_fade_table32[eax*4]
6272     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
6273     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
6274
6275     sbb     ebp,ebp                     // get -1 if carry
6276     mov     [edi+16],eax                  // store pixel 3
6277
6278     add     ebx,edx                     // increment u fraction
6279     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6280     mov         ah, bh
6281     mov         eax, gr_fade_table32[eax*4]
6282     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
6283     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
6284
6285     sbb     ebp,ebp                     // get -1 if carry
6286     mov     [edi+20],eax                  // store pixel 3
6287
6288     add     ebx,edx                     // increment u fraction
6289     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6290     mov         ah, bh
6291     mov         eax, gr_fade_table32[eax*4]
6292     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
6293     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
6294
6295     sbb     ebp,ebp                     // get -1 if carry
6296     mov     [edi+24],eax                  // store pixel 3
6297
6298     add     ebx,edx                     // increment u fraction
6299     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6300     mov         ah, bh
6301     mov         eax, gr_fade_table32[eax*4]
6302     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
6303     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
6304
6305     sbb     ebp,ebp                     // get -1 if carry
6306     mov     [edi+28],eax                  // store pixel 3
6307
6308     add     ebx,edx                     // increment u fraction
6309     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6310     mov         ah, bh
6311     mov         eax, gr_fade_table32[eax*4]
6312     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
6313     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
6314
6315     sbb     ebp,ebp                     // get -1 if carry
6316     mov     [edi+32],eax                  // store pixel 3
6317
6318     add     ebx,edx                     // increment u fraction
6319     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6320     mov         ah, bh
6321     mov         eax, gr_fade_table32[eax*4]
6322     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
6323     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
6324
6325     sbb     ebp,ebp                     // get -1 if carry
6326     mov     [edi+36],eax                  // store pixel 3
6327
6328     add     ebx,edx                     // increment u fraction
6329     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6330     mov         ah, bh
6331     mov         eax, gr_fade_table32[eax*4]
6332     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
6333     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
6334
6335     sbb     ebp,ebp                     // get -1 if carry
6336     mov     [edi+40],eax                  // store pixel 3
6337
6338     add     ebx,edx                     // increment u fraction
6339     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6340     mov         ah, bh
6341     mov         eax, gr_fade_table32[eax*4]
6342
6343
6344     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
6345     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
6346
6347     sbb     ebp,ebp                     // get -1 if carry
6348     mov     [edi+44],eax                  // store pixel 3
6349
6350     add     ebx,edx                     // increment u fraction
6351     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6352     mov         ah, bh
6353     mov         eax, gr_fade_table32[eax*4]
6354
6355
6356     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
6357     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
6358
6359     sbb     ebp,ebp                     // get -1 if carry
6360     mov     [edi+48],eax                  // store pixel 3
6361
6362     add     ebx,edx                     // increment u fraction
6363     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6364     mov         ah, bh
6365     mov         eax, gr_fade_table32[eax*4]
6366
6367
6368     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
6369     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
6370
6371     sbb     ebp,ebp                     // get -1 if carry
6372     mov     [edi+52],eax                  // store pixel 3
6373
6374     add     ebx,edx                     // increment u fraction
6375     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6376     mov         ah, bh
6377     mov         eax, gr_fade_table32[eax*4]
6378
6379
6380     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
6381     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
6382
6383     sbb     ebp,ebp                     // get -1 if carry
6384     mov     [edi+56],eax                  // store pixel 3
6385
6386     add     ebx,edx                     // increment u fraction
6387     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6388     mov         ah, bh
6389     mov         eax, gr_fade_table32[eax*4]
6390
6391
6392     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
6393     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
6394
6395     sbb     ebp,ebp                     // get -1 if carry
6396     mov     [edi+60],eax                  // store pixel 3
6397
6398     add     ebx,edx                     // increment u fraction
6399     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6400     mov         ah, bh
6401     mov         eax, gr_fade_table32[eax*4]
6402
6403
6404     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
6405     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
6406
6407     sbb     ebp,ebp                     // get -1 if carry
6408     mov     [edi+64],eax                  // store pixel 3
6409
6410     add     ebx,edx                     // increment u fraction
6411     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6412     mov         ah, bh
6413     mov         eax, gr_fade_table32[eax*4]
6414
6415
6416     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
6417     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
6418
6419     sbb     ebp,ebp                     // get -1 if carry
6420     mov     [edi+68],eax                  // store pixel 3
6421
6422     add     ebx,edx                     // increment u fraction
6423     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6424     mov         ah, bh
6425     mov         eax, gr_fade_table32[eax*4]
6426
6427
6428     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
6429     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
6430
6431     sbb     ebp,ebp                     // get -1 if carry
6432     mov     [edi+72],eax                  // store pixel 3
6433
6434     add     ebx,edx                     // increment u fraction
6435     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6436     mov         ah, bh
6437     mov         eax, gr_fade_table32[eax*4]
6438
6439
6440     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
6441     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
6442
6443     sbb     ebp,ebp                     // get -1 if carry
6444     mov     [edi+76],eax                  // store pixel 3
6445
6446     add     ebx,edx                     // increment u fraction
6447     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6448     mov         ah, bh
6449     mov         eax, gr_fade_table32[eax*4]
6450
6451
6452     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
6453     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
6454
6455     sbb     ebp,ebp                     // get -1 if carry
6456     mov     [edi+80],eax                  // store pixel 3
6457
6458     add     ebx,edx                     // increment u fraction
6459     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6460     mov         ah, bh
6461     mov         eax, gr_fade_table32[eax*4]
6462
6463
6464     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
6465     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
6466
6467     sbb     ebp,ebp                     // get -1 if carry
6468     mov     [edi+84],eax                  // store pixel 3
6469
6470     add     ebx,edx                     // increment u fraction
6471     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6472     mov         ah, bh
6473     mov         eax, gr_fade_table32[eax*4]
6474
6475
6476     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
6477     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
6478
6479     sbb     ebp,ebp                     // get -1 if carry
6480     mov     [edi+88],eax                  // store pixel 3
6481
6482     add     ebx,edx                     // increment u fraction
6483     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6484     mov         ah, bh
6485     mov         eax, gr_fade_table32[eax*4]
6486
6487
6488     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
6489     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
6490
6491     sbb     ebp,ebp                     // get -1 if carry
6492     mov     [edi+92],eax                  // store pixel 3
6493
6494     add     ebx,edx                     // increment u fraction
6495     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6496     mov         ah, bh
6497     mov         eax, gr_fade_table32[eax*4]
6498
6499
6500     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
6501     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
6502
6503     sbb     ebp,ebp                     // get -1 if carry
6504     mov     [edi+96],eax                  // store pixel 3
6505
6506     add     ebx,edx                     // increment u fraction
6507     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6508     mov         ah, bh
6509     mov         eax, gr_fade_table32[eax*4]
6510
6511
6512     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
6513     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
6514
6515     sbb     ebp,ebp                     // get -1 if carry
6516     mov     [edi+100],eax                  // store pixel 3
6517
6518     add     ebx,edx                     // increment u fraction
6519     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6520     mov         ah, bh
6521     mov         eax, gr_fade_table32[eax*4]
6522
6523
6524     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
6525     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
6526
6527
6528
6529     sbb     ebp,ebp                     // get -1 if carry
6530     mov     [edi+104],eax                  // store pixel 3
6531
6532     add     ebx,edx                     // increment u fraction
6533     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6534     mov         ah, bh
6535     mov         eax, gr_fade_table32[eax*4]
6536
6537
6538     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
6539     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
6540
6541     sbb     ebp,ebp                     // get -1 if carry
6542     mov     [edi+108],eax                  // store pixel 3
6543
6544     add     ebx,edx                     // increment u fraction
6545     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6546     mov         ah, bh
6547     mov         eax, gr_fade_table32[eax*4]
6548
6549     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
6550     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
6551
6552     sbb     ebp,ebp                     // get -1 if carry
6553     mov     [edi+112],eax                  // store pixel 4
6554
6555     add     ebx,edx                     // increment u fraction
6556     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6557     mov         ah, bh
6558     mov         eax, gr_fade_table32[eax*4]
6559
6560     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
6561     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
6562
6563     sbb     ebp,ebp                     // get -1 if carry
6564     mov     [edi+116],eax                  // store pixel 5
6565
6566     add     ebx,edx                     // increment u fraction
6567     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6568     mov         ah, bh
6569     mov         eax, gr_fade_table32[eax*4]
6570
6571     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
6572     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
6573
6574     sbb     ebp,ebp                     // get -1 if carry
6575     mov     [edi+120],eax                  // store pixel 6
6576
6577     add     ebx,edx                     // increment u fraction
6578
6579     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6580     mov         ah, bh
6581     mov         eax, gr_fade_table32[eax*4]
6582
6583     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
6584
6585     mov     [edi+124],eax                 // store pixel 7
6586
6587
6588     
6589     ; ************** Okay to Access Stack Frame ****************
6590     ; ************** Okay to Access Stack Frame ****************
6591     ; ************** Okay to Access Stack Frame ****************
6592
6593
6594     ; the fdiv is done, finish right    ; st0  st1  st2  st3  st4  st5  st6  st7
6595                                         ; ZR   V/ZR 1/ZR U/ZR UL   VL
6596
6597     fld     st                          ; ZR   ZR   V/ZR 1/ZR U/ZR UL   VL
6598     fmul    st,st(2)                    ; VR   ZR   V/ZR 1/ZR U/ZR UL   VL
6599     fxch    st(1)                       ; ZR   VR   V/ZR 1/ZR U/ZR UL   VL
6600     fmul    st,st(4)                    ; UR   VR   V/ZR 1/ZR U/ZR UL   VL
6601
6602     add     edi,128                       ; increment to next span
6603     dec     Tmap1.Subdivisions              ; decrement span count
6604     jnz     SpanLoop                    ; loop back
6605
6606         // save new lighting values
6607 //      xor     eax, eax
6608 //      mov     ax, bx
6609 //      mov     Tmap1.fx_l, eax
6610
6611 //      xor     eax, eax
6612 //      mov     ax, dx
6613 //      mov     Tmap1.fx_dl_dx, eax
6614
6615 HandleLeftoverPixels:
6616 //      jmp     FPUReturn
6617
6618     mov     esi,Tmap1.pixptr          ; load texture pointer
6619
6620     ; edi = dest dib bits
6621     ; esi = current texture dib bits
6622     ; at this point the FPU contains    ; st0  st1  st2  st3  st4  st5  st6  st7
6623     ; inv. means invalid numbers        ; inv. inv. inv. inv. inv. UL   VL
6624
6625     cmp     Tmap1.WidthModLength,0          ; are there remaining pixels to draw?
6626     jz      FPUReturn                   ; nope, pop the FPU and bail
6627
6628     ; convert left side coords          ; st0  st1  st2  st3  st4  st5  st6  st7
6629
6630     fld     st(5)                       ; UL   inv. inv. inv. inv. inv. UL   VL
6631     fmul    Tmap1.FixedScale                ; UL16 inv. inv. inv. inv. inv. UL   VL
6632     fistp   Tmap1.UFixed                    ; inv. inv. inv. inv. inv. UL   VL
6633
6634     fld     st(6)                       ; VL   inv. inv. inv. inv. inv. UL   VL
6635     fmul    Tmap1.FixedScale                // VL16 inv. inv. inv. inv. inv. UL   VL
6636     fistp   Tmap1.VFixed                    ; inv. inv. inv. inv. inv. UL   VL
6637
6638     dec     Tmap1.WidthModLength            ; calc how many steps to take
6639     jz      OnePixelSpan                ; just one, don't do deltas
6640
6641     ; calculate right edge coordinates  ; st0  st1  st2  st3  st4  st5  st6  st7
6642     ; r -> R+1
6643
6644     ; @todo rearrange things so we don't need these two instructions
6645     fstp    Tmap1.FloatTemp                 ; inv. inv. inv. inv. UL   VL
6646     fstp    Tmap1.FloatTemp                 ; inv. inv. inv. UL   VL
6647
6648     fld     Tmap1.RightVOverZ           ; V/Zr inv. inv. inv. UL   VL
6649     fsub    Tmap1.dVOverZdX             ; V/ZR inv. inv. inv. UL   VL
6650     fld     Tmap1.RightUOverZ           ; U/Zr V/ZR inv. inv. inv. UL   VL
6651     fsub    Tmap1.dUOverZdX             ; U/ZR V/ZR inv. inv. inv. UL   VL
6652     fld     Tmap1.RightOneOverZ              ; 1/Zr U/ZR V/ZR inv. inv. inv. UL   VL
6653     fsub    Tmap1.dOneOverZdX           ; 1/ZR U/ZR V/ZR inv. inv. inv. UL   VL
6654
6655     fdivr   Tmap1.One                       ; ZR   U/ZR V/ZR inv. inv. inv. UL   VL
6656
6657     fmul    st(1),st                    ; ZR   UR   V/ZR inv. inv. inv. UL   VL
6658     fmulp   st(2),st                    ; UR   VR   inv. inv. inv. UL   VL
6659
6660     ; calculate deltas                  ; st0  st1  st2  st3  st4  st5  st6  st7
6661
6662     fsubr   st(5),st                    ; UR   VR   inv. inv. inv. dU   VL
6663     fxch    st(1)                       ; VR   UR   inv. inv. inv. dU   VL
6664     fsubr   st(6),st                    ; VR   UR   inv. inv. inv. dU   dV
6665     fxch    st(6)                       ; dV   UR   inv. inv. inv. dU   VR
6666
6667     fidiv   Tmap1.WidthModLength            ; dv   UR   inv. inv. inv. dU   VR
6668     fmul    Tmap1.FixedScale                ; dv16 UR   inv. inv. inv. dU   VR
6669     fistp   Tmap1.DeltaV                    ; UR   inv. inv. inv. dU   VR
6670
6671     fxch    st(4)                       ; dU   inv. inv. inv. UR   VR
6672     fidiv   Tmap1.WidthModLength            ; du   inv. inv. inv. UR   VR
6673     fmul    Tmap1.FixedScale                ; du16 inv. inv. inv. UR   VR
6674     fistp   Tmap1.DeltaU                    ; inv. inv. inv. UR   VR
6675
6676     ; @todo gross!  these are to line up with the other loop
6677     fld     st(1)                       ; inv. inv. inv. inv. UR   VR
6678     fld     st(2)                       ; inv. inv. inv. inv. inv. UR   VR
6679
6680 //jmp OldWay
6681
6682
6683         ; setup delta values
6684         mov     eax, Tmap1.DeltaV       // get v 16.16 step
6685         mov     ebx, eax                                                // copy it
6686         sar     eax, 16                                         // get v int step
6687         shl     ebx, 16                                         // get v frac step
6688         mov     Tmap1.DeltaVFrac, ebx   // store it
6689         imul    eax, Tmap1.src_offset   // calc texture step for v int step
6690         
6691         mov     ebx, Tmap1.DeltaU                       // get u 16.16 step
6692         mov     ecx, ebx                                                // copy it
6693         sar     ebx, 16                                         // get the u int step
6694         shl     ecx, 16                                         // get the u frac step
6695         mov     Tmap1.DeltaUFrac, ecx                   // store it
6696         add     eax, ebx                                                // calc uint + vint step
6697         mov     Tmap1.UVintVfracStepVNoCarry, eax       // save whole step in non-v-carry slot
6698         add     eax, Tmap1.src_offset                           // calc whole step + v carry
6699         mov     Tmap1.UVintVfracStepVCarry, eax // save in v-carry slot
6700
6701
6702
6703 OnePixelSpan:
6704
6705 /*
6706 ; check coordinate ranges
6707         mov     eax, Tmap1.UFixed
6708         cmp     eax, Tmap1.MinUFixed
6709         jge     UNotTooSmall_2
6710         mov     eax, Tmap1.MinUFixed
6711         mov     Tmap1.UFixed, eax
6712         jmp     CheckV_2
6713 UNotTooSmall_2: 
6714         cmp     eax, Tmap1.MaxUFixed
6715         jle     CheckV_2
6716         mov     eax, Tmap1.MaxUFixed
6717         mov     Tmap1.UFixed, eax
6718 CheckV_2:
6719         mov     eax, Tmap1.VFixed
6720         cmp     eax, Tmap1.MinVFixed
6721         jge     VNotTooSmall_2
6722         mov     eax, Tmap1.MinVFixed
6723         mov     Tmap1.VFixed, eax
6724         jmp     DoneCheck_2
6725 VNotTooSmall_2: 
6726         cmp     eax, Tmap1.MaxVFixed
6727         jle     DoneCheck_2
6728         mov     eax, Tmap1.MaxVFixed
6729         mov     Tmap1.VFixed, eax
6730 DoneCheck_2:
6731 */
6732
6733
6734
6735
6736         ; setup initial coordinates
6737         mov     esi, Tmap1.UFixed                       // get u 16.16
6738         mov     ebx, esi                                                // copy it
6739         sar     esi, 16                                         // get integer part
6740         shl     ebx, 16                                         // get fractional part
6741
6742         mov     ecx, Tmap1.VFixed                       // get v 16.16 
6743         mov     edx, ecx                                                // copy it
6744         sar     edx, 16                                         // get integer part
6745         shl     ecx, 16                                         // get fractional part
6746         imul    edx, Tmap1.src_offset           // calc texture scanline address
6747         add     esi, edx                                                        // calc texture offset
6748         add     esi, Tmap1.pixptr                       // calc address
6749         
6750         ; set edi = address of first pixel to modify
6751 ;       mov     edi, Tmap1.dest_row_data
6752
6753
6754
6755
6756         mov     eax, Tmap1.fx_l
6757         shr     eax, 8
6758         mov     bx, ax
6759
6760         mov     edx, Tmap1.DeltaUFrac
6761
6762         cmp     Tmap1.WidthModLength, 1
6763         jle     NoDeltaLight
6764
6765         push    ebx
6766         
6767         mov     ebx, Tmap1.fx_l_right
6768         shr     ebx, 8
6769         
6770         sub     ebx, eax
6771         mov     eax, ebx
6772         
6773 #if 0
6774         // slow but maybe better
6775         push    edx
6776         cdq
6777         mov     ebx, Tmap1.WidthModLength 
6778         dec     ebx
6779         idiv    ebx
6780         pop     edx
6781 #else
6782         mov     eax, Tmap1.fx_dl_dx
6783         shr     eax, 8
6784 #endif
6785
6786         mov     dx, ax
6787
6788         pop     ebx
6789
6790 NoDeltaLight:
6791
6792         inc     Tmap1.WidthModLength
6793         mov     eax,Tmap1.WidthModLength
6794         shr     eax, 1
6795         jz              one_more_pix
6796         pushf
6797         mov     Tmap1.WidthModLength, eax
6798
6799         xor     eax, eax
6800
6801     mov     al,[edi]                    // preread the destination cache line
6802
6803 NextPixel:
6804     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6805     mov         ah, bh
6806     mov         eax, gr_fade_table32[eax*4]
6807
6808     add     ecx,Tmap1.DeltaVFrac            // increment v fraction
6809     sbb     ebp,ebp                     // get -1 if carry
6810     add     ebx,edx                     // increment u fraction
6811     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
6812     mov     [edi+0],eax                  // store pixel 0
6813
6814     add     ecx,Tmap1.DeltaVFrac        // increment v fraction
6815     sbb     ebp,ebp                     // get -1 if carry
6816     add     ebx,edx                     // increment u fraction
6817     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6818     mov         ah, bh
6819     mov         eax, gr_fade_table32[eax*4]
6820
6821     adc     esi,UVintVfracStep[4*ebp]  // add in step ints & carries
6822     mov     [edi+4],eax                  // store pixel 1
6823
6824         add     edi, 8
6825         dec     Tmap1.WidthModLength
6826         jg              NextPixel
6827
6828         popf
6829         jnc     FPUReturn
6830
6831 one_more_pix:   
6832
6833     movzx   eax,byte ptr [esi]                    // get texture pixel 0
6834     mov         ah, bh
6835     mov         eax, gr_fade_table32[eax*4]
6836     mov     [edi],eax                  // store pixel 2
6837
6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
6850 /* 
6851 OldWay:         // This is 6% slower than above
6852
6853     mov     ebx,Tmap1.UFixed                ; get starting coordinates
6854     mov     ecx,Tmap1.VFixed                ; for span
6855  
6856     ; leftover pixels loop
6857     ; edi = dest dib bits
6858     ; esi = texture dib bits
6859
6860     ; ebx = u 16.16
6861     ; ecx = v 16.16
6862
6863
6864     mov     eax,ecx                     ; copy v
6865     sar     eax,16                      ; int(v)
6866     imul    eax,Tmap1.src_offset      ; scan offset
6867     mov     edx,ebx                     ; copy u
6868     sar     edx,16                      ; int(u)
6869     add     eax,edx                     ; texture offset
6870     mov     al,[esi+eax]                ; get source pixel
6871 mov al, 0
6872     mov     [edi],al                    ; store it
6873     inc     edi
6874     add     ebx,Tmap1.DeltaU                  ; increment u coordinate
6875     add     ecx,Tmap1.DeltaV                  ; increment v coordinate
6876
6877     dec     Tmap1.WidthModLength            ; decrement loop count
6878     jl     FPUReturn                ; finish up
6879          
6880
6881 LeftoverLoop:
6882     mov     eax,ecx                     ; copy v
6883     sar     eax,16                      ; int(v)
6884     imul    eax,Tmap1.src_offset      ; scan offset
6885     mov     edx,ebx                     ; copy u
6886     sar     edx,16                      ; int(u)
6887     add     eax,edx                     ; texture offset
6888     mov     al,[esi+eax]                ; get source pixel
6889     mov     [edi],al                    ; store it
6890     inc     edi
6891     add     ebx,Tmap1.DeltaU                  ; increment u coordinate
6892     add     ecx,Tmap1.DeltaV                  ; increment v coordinate
6893
6894     dec     Tmap1.WidthModLength            ; decrement loop count
6895     jge     LeftoverLoop                ; finish up
6896 */
6897
6898 FPUReturn:
6899
6900     ; busy FPU registers:               ; st0  st1  st2  st3  st4  st5  st6  st7
6901                                         ; xxx  xxx  xxx  xxx  xxx  xxx  xxx
6902     ffree   st(0)
6903     ffree   st(1)
6904     ffree   st(2)
6905     ffree   st(3)
6906     ffree   st(4)
6907     ffree   st(5)
6908     ffree   st(6)
6909
6910 //Return:
6911
6912     fldcw   Tmap1.OldFPUCW                  // restore the FPU
6913
6914         pop     edi
6915         pop     esi
6916         pop     ebp
6917         pop     ebx
6918         pop     edx
6919         pop     ecx
6920         pop     eax
6921         }
6922
6923
6924 }
6925
6926
6927
6928
6929 add edx,DeltaVFrac        ; Add in 0.32 DeltaVFrac to VFrac
6930 sbb ebp,ebp               ; ebp will equal -1 if there was a carry
6931 mov BYTE PTR [edi], al    ; blit destination pixel
6932 mov al, BYTE PTR [esi]    ; get next texel
6933 add ecx,ebx               ; add 0.32 DeltaUFrac to UFrac, plus light
6934 adc esi, [UVStepCarry1+(ebp*4)]
6935 mov ah, ch                ; move lighting value into place
6936 mov al, ShadeTable[eax]   ; Get shaded pixel
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947 #endif
6948