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