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