source: golgotha/src/golg/win95/texture_asm.hh @ 80

Last change on this file since 80 was 80, checked in by Sam Hocevar, 11 years ago
  • Adding the Golgotha source code. Not sure what's going to be interesting in there, but since it's all public domain, there's certainly stuff to pick up.
File size: 22.4 KB
Line 
1/********************************************************************** <BR>
2  This file is part of Crack dot Com's free source code release of
3  Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
4  information about compiling & licensing issues visit this URL</a>
5  <PRE> If that doesn't help, contact Jonathan Clark at
6  golgotha_source@usa.net (Subject should have "GOLG" in it)
7***********************************************************************/
8
9#ifndef _WIN95_ASM_HH_
10#define _WIN95_ASM_HH_
11
12//June 7th... Jonathon finally talked me into inline...
13//globals...  These are referenced as memory offsets
14//so they need to be global 'c' type things
15//when these are totally finalized, re-arrange these in
16//tmapper soft so that the variables used together are in
17//the same cache line
18
19//external references
20extern "C" w32 cTable[2*256*32];   //low and high bits of color
21extern "C" w16 *r1_software_texture_ptr;
22extern "C" w8  r1_software_twidth_log2;
23extern "C" w16 *pixel_on;
24
25//external declarations
26extern "C"
27{
28  i4_float FixedScale  = 65536.f;
29  i4_float FixedScale8 = 8192.f;
30  i4_float LightScale  = 2031616.f;
31  w16 zBuffer[640*480];   //low and high bits of color 
32  i4_float One = 1.f;
33  i4_float FloatTemp;
34  w32 UVintVfracStepV[2];
35  w32 DeltaVFrac;
36  w32 DeltaUFrac;
37  w32 LVal;
38  w32 LDelta;
39  w32 pTex;
40}
41
42
43void draw_scanline_white_pc(edgeGrad *left, edgeGrad *right)
44{
45  //locals on the stack
46  w32 Subdivisions;
47  w32 WidthModLength;
48  w32 DeltaU;
49  w32 DeltaV;
50  w32 UFixed;
51  w32 VFixed;
52  w16 FPUCW;
53  w16 OldFPUCW;
54  sw32 blarg;
55
56  if (((sw32)r1_software_texture_ptr) & 1)
57  {
58    _asm
59    {
60      mov Subdivisions,0
61    }   
62    return;
63  }
64
65  _asm {
66    //this should be moved out
67    ; put the FPU in 32 bit mode
68    fstcw   [OldFPUCW]                    ; store copy of CW
69    mov     ax,OldFPUCW                   ; get it in ax
70    and     eax,0ffh                      ; 24 bit precision
71    mov     [FPUCW],ax                    ; store it
72    fldcw   [FPUCW]                       ; load the FPU
73
74    mov     ebx,left                      ;
75    mov     esi,r1_software_pixel_on      ; grab screen pointer
76    mov     edx,right                     ;
77    mov     eax,[ebx]edgeGrad.X           ; left x
78    mov     ecx,[edx]edgeGrad.X           ; edx = right x
79
80    sub     ecx,eax                       ; edx = width
81    jle     whtp_Return                   ; no pixels to draw, get out
82
83    mov     [pTex],ecx                    ; just for a temp so it can be fild'ed
84
85//note below the fdiv... if more values need to be interpolated based on the scanline
86//width... you should do 1/WID and use muls... this is faster cuz theres only one
87
88    ; calc this scanlines light step      ; FPU Stack
89                                          ; st0  st1  st2  st3  st4  st5  st6  st7
90    fild    dword ptr [pTex]              ; WID
91    fld     dword ptr [edx]edgeGrad.r     ; LR   WID
92    fld     dword ptr [ebx]edgeGrad.r     ; LL   LR   WID
93    fld     st                            ; LL   LL   LR   WID
94    fmul    [LightScale]                  ; LL16 LL   LR   WID
95    fistp   [LVal]                        ; LL   LR   WID
96    fsubp   st(1),st                      ; LD   WID
97    fdiv    st,st(1)                      ; LS   WID
98    mov     ebx,eax
99
100//heres an unused scanline z fill (inaccurate)
101;    mov     ax,word ptr [sortKey]
102;    mov     edi,zBuffer
103
104    mov     edx,ecx
105    mov     edi,r1_software_texture_ptr
106
107//rest of the z fill thing that isn't used
108;    rep     stosw
109
110    mov     cl,r1_software_twidth_log2
111    mov     byte ptr whtp_twidth_log2_patch0+2, cl
112    shr     edi,1                         ; pray that it's aligned!
113    mov     byte ptr whtp_twidth_log2_patch1+2, cl
114    mov     pTex,edi
115    mov     byte ptr whtp_twidth_log2_patch2+2, cl
116    mov     edi,esi                       ; edi = dest pointer
117    mov     byte ptr whtp_twidth_log2_patch3+2, cl
118
119//is pixel_on.add being used?  If not the shl is needed
120;    shl     ebx,1
121
122    mov     eax,edx                       ; eax and edx = width
123
124//this is also needed if pixel_on.add isn't used
125;    add     edi,ebx
126
127    ; edi = pointer to start pixel in dest dib
128    ; edx = spanwidth
129
130    shr     edx,3                         ; ecx = width / subdivision length
131    and     eax,7                         ; eax = width mod subdivision length
132
133    //the next line is avoiding a far jump which was the
134    //only opcode inline would generate... it simply skips down to
135    //to mov [Subdivisions],edx two instructions down
136    __asm _emit 0x75 __asm _emit 0x06     ;jnz     @f  any leftover?
137
138    dec     edx                           ; no, so special case last span
139    mov     eax,8                         ; it's 8 pixels long
140    mov     [Subdivisions],edx            ; store widths
141    mov     [WidthModLength],eax
142
143    fmul    [LightScale]                 
144    fxch    st(1)
145    fistp   [LDelta]
146    fistp   [LDelta]
147
148
149    mov     ebx,left                      ; get left edge pointer
150
151    //try not to play around with the ordering here later...
152    //this is the most optimal stack ordering possible
153    ; calculate ULeft and VLeft           ; FPU Stack (ZL = ZLeft)
154                                          ; st0  st1  st2  st3  st4  st5  st6  st7
155    fld     [ebx]edgeGrad.VOverZ          ; V/ZL
156    fld     [ebx]edgeGrad.UOverZ          ; U/ZL V/ZL
157    fld     [ebx]edgeGrad.OneOverZ        ; 1/ZL U/ZL V/ZL
158    fld1                                  ; 1    1/ZL U/ZL V/ZL
159    fdiv    st,st(1)                      ; ZL   1/ZL U/ZL V/ZL
160
161    //here there is room for alot of integer ops, but this is only done
162    //once... This would be a good spot for the zbuffer shitcan method
163
164    fld     st                            ; ZL   ZL   1/ZL U/ZL V/ZL
165    fmul    st,st(4)                      ; VL   ZL   1/ZL U/ZL V/ZL
166    fxch    st(1)                         ; ZL   VL   1/ZL U/ZL V/ZL
167    fmul    st,st(3)                      ; UL   VL   1/ZL U/ZL V/ZL
168    fstp    st(5)                         ; VL   1/ZL U/ZL V/ZL UL
169    fstp    st(5)                         ; 1/ZL U/ZL V/ZL UL   VL
170
171    //the dword ptrs below shut up compiler warnings (though they don't do qwords)
172    //notice the adds... that simply steps to the end of the next span ahead of time
173    ; calculate right side OverZ terms    ; st0  st1  st2  st3  st4  st5  st6  st7
174    fadd    dword ptr grads.dOneOverZdX8  ; 1/ZR U/ZL V/ZL UL   VL
175    fxch    st(1)                         ; U/ZL 1/ZR V/ZL UL   VL
176    fadd    dword ptr grads.dUOverZdX8    ; U/ZR 1/ZR V/ZL UL   VL
177    fxch    st(2)                         ; V/ZL 1/ZR U/ZR UL   VL
178    fadd    dword ptr grads.dVOverZdX8    ; V/ZR 1/ZR U/ZR UL   VL
179 
180
181    //here's the equivlent of the fpu loop at the bottom, only theres an fdiv
182    //here that has plenty of room for int ops between
183    ; calculate right side coords       ; st0  st1  st2  st3  st4  st5  st6  st7
184
185    fld1                                ; 1    V/ZR 1/ZR U/ZR UL   VL
186    ; @todo overlap this guy
187    fdiv    st,st(2)                    ; ZR   V/ZR 1/ZR U/ZR UL   VL
188    fld     st                          ; ZR   ZR   V/ZR 1/ZR U/ZR UL   VL
189    fmul    st,st(2)                    ; VR   ZR   V/ZR 1/ZR U/ZR UL   VL
190    fxch    st(1)                       ; ZR   VR   V/ZR 1/ZR U/ZR UL   VL
191    fmul    st,st(4)                    ; UR   VR   V/ZR 1/ZR U/ZR UL   VL
192
193    test    edx,edx                     ; check for any full spans
194    jz      whtp_HandleLeftoverPixels
195
196whtp_SpanLoop:
197
198    ; at this point the FPU contains      ; st0  st1  st2  st3  st4  st5  st6  st7
199                                          ; UR   VR   V/ZR 1/ZR U/ZR UL   VL
200
201    ; convert left side coords
202
203    fld     st(5)                         ; UL   UR   VR   V/ZR 1/ZR U/ZR UL   VL
204    fmul    [FixedScale]                  ; UL8 UR   VR   V/ZR 1/ZR U/ZR UL   VL
205    fistp   [UFixed]                      ; UR   VR   V/ZR 1/ZR U/ZR UL   VL
206
207    fld     st(6)                         ; VL   UR   VR   V/ZR 1/ZR U/ZR UL   VL
208    fmul    [FixedScale]                  ; VL8 UR   VR   V/ZR 1/ZR U/ZR UL   VL
209    fistp   [VFixed]                      ; UR   VR   V/ZR 1/ZR U/ZR UL   VL
210
211    ; calculate deltas                    ; st0  st1  st2  st3  st4  st5  st6  st7
212
213    fsubr   st(5),st                      ; UR   VR   V/ZR 1/ZR U/ZR dU   VL
214    fxch    st(1)                         ; VR   UR   V/ZR 1/ZR U/ZR dU   VL
215    fsubr   st(6),st                      ; VR   UR   V/ZR 1/ZR U/ZR dU   dV
216    fxch    st(6)                         ; dV   UR   V/ZR 1/ZR U/ZR dU   VR
217
218    fmul    [FixedScale8]                 ; dV8  UR   V/ZR 1/ZR U/ZR dU   VR
219    fistp   [DeltaV]                      ; UR   V/ZR 1/ZR U/ZR dU   VR
220
221    fxch    st(4)                         ; dU   V/ZR 1/ZR U/ZR UR   VR
222    fmul    [FixedScale8]                 ; dU8  V/ZR 1/ZR U/ZR UR   VR
223    fistp   [DeltaU]                      ; V/ZR 1/ZR U/ZR UR   VR
224
225    ; increment terms for next span       ; st0  st1  st2  st3  st4  st5  st6  st7
226    ; Right terms become Left terms---->  ; V/ZL 1/ZL U/ZL UL   VL
227
228    fadd    dword ptr grads.dVOverZdX8              ; V/ZR 1/ZL U/ZL UL   VL
229    fxch    st(1)                         ; 1/ZL V/ZR U/ZL UL   VL
230    fadd    dword ptr grads.dOneOverZdX8            ; 1/ZR V/ZR U/ZL UL   VL
231    fxch    st(2)                         ; U/ZL V/ZR 1/ZR UL   VL
232    fadd    dword ptr grads.dUOverZdX8              ; U/ZR V/ZR 1/ZR UL   VL
233    fxch    st(2)                         ; 1/ZR V/ZR U/ZR UL   VL
234    fxch    st(1)                         ; V/ZR 1/ZR U/ZR UL   VL
235
236    //here's the span fdiv... avoid any fpu ops after this, or any imuls
237    ; calculate right side coords         ; st0  st1  st2  st3  st4  st5  st6  st7
238    fld1                                  ; 1    V/ZR 1/ZR U/ZR UL   VL
239    fdiv    st,st(2)                      ; ZR   V/ZR 1/ZR U/ZR UL   VL
240
241    //see hecker's articles for an explaination of below... it's too big
242    //to comment in
243    ; do pre span delta setup and start modify
244
245    mov     esi,[DeltaV]                  ; get v 16.16 step
246    mov     ebx,esi                       ; split up into int and frac
247    sar     esi,16
248    shl     ebx,16
249    mov     [DeltaVFrac],ebx
250whtp_twidth_log2_patch0:
251    shl     esi,3
252
253    mov     ebx,[DeltaU]                  ; get u 16.16 step
254    mov     eax,ebx
255    shl     eax,16
256    sar     ebx,16
257    mov     [DeltaUFrac],eax
258    add     esi,ebx
259    mov     ebx,1
260    mov     [4+UVintVfracStepV],esi       ; non V carry slot
261whtp_twidth_log2_patch1:
262    shl     ebx,3                         ; this is to get the texwidth
263    add     esi,ebx
264    mov     [UVintVfracStepV],esi         ; V carry slot
265
266    ; setup initial coordinates
267
268    //see the file gradients.txt in hecker's code pack for an explaination
269    //of the modifiers... it's pretty long
270    mov     esi,[UFixed]                  ; get u 16.16 fixedpoint coordinate
271    add     esi,dword ptr grads.dUdXModifier
272    mov     ecx,[VFixed]                  ; and v... before ebp gets pushed
273    add     ecx,dword ptr grads.dVdXModifier
274   
275    mov     blarg,ebp
276
277    push    ebp
278    mov     ebp,esi
279    sar     esi,16
280    mov     edx,ecx
281    shl     ebp,16
282
283    sar     edx,16
284    shl     ecx,16
285whtp_twidth_log2_patch2:
286    shl     edx,3
287
288    add     esi,edx                       ; move texture to offset
289    xor     eax,eax                       ; clear eax
290    mov     edx,[LVal]
291    add     esi,pTex
292
293    ; edi = dest dib bits at current pixel
294    ; esi = texture pointer at current texel
295    ; ebp = u fraction 0.32
296    ; ecx = v fraction 0.32
297    ; edx = Light value and bit storage
298    ; ebx = v carry scratch
299    ;
300    ; edx rolls to act as temp storage, and also to
301    ; make the light value an index into the ctable
302
303    //theres a stall in this loop... it's only one cycle but it might be
304    //somehow avoided... I ran outta time.  It's the V pipe add below rol edx, 16
305    mov   al,[1+esi*2]
306
307    rol   edx,16                          ; get the low word usable
308    add   ecx,[DeltaVFrac]
309
310    sbb   ebx,ebx                         ; U pipe only
311    mov   ah,dl
312
313    mov   dh,[2*esi]
314    add   ebp,[DeltaUFrac]
315
316    adc   esi,[4+UVintVfracStepV+ebx*4]   ; U pipe only
317    mov   bl,dh
318
319    mov   bh,dl
320    mov   eax,dword ptr[cTable+8000h+eax*4]
321
322    and   ebx,0ffffh
323    mov   dh,0
324
325    rol   edx,16
326    add   eax,dword ptr[cTable+ebx*4]     ; One cycle stall here U exp flow i think
327
328    add   edx,[LDelta]
329    mov   [edi],al
330
331    rol   edx,16
332    mov   [edi+1],ah
333
334    add   ecx,[DeltaVFrac]
335    mov   ah,dl
336
337    sbb   ebx,ebx                         ; U pipe only
338    mov   dh,[esi*2]
339
340    add   ebp,[DeltaUFrac]
341    mov   al,[1+esi*2]
342
343    adc   esi,[4+UVintVfracStepV+ebx*4]      ; U pipe only
344    mov   bl,dh
345
346    mov   eax,dword ptr[cTable+8000h+eax*4]
347    mov   bh,dl
348
349    mov   dh,0
350    and   ebx,0ffffh
351
352    rol   edx,16
353    add   eax,dword ptr[cTable+ebx*4]
354
355    add   edx,[LDelta]
356    mov   [edi+2],al
357
358    rol   edx,16
359    mov   [edi+3],ah
360
361    add   ecx,[DeltaVFrac]
362    mov   ah,dl
363
364    sbb   ebx,ebx                         ; U pipe only
365    mov   dh,[esi*2]
366
367    add   ebp,[DeltaUFrac]
368    mov   al,[1+esi*2]
369
370    adc   esi,[4+UVintVfracStepV+ebx*4]      ; U pipe only
371    mov   bl,dh
372
373    mov   eax,dword ptr[cTable+8000h+eax*4]
374    mov   bh,dl
375
376    mov   dh,0
377    and   ebx,0ffffh
378
379    rol   edx,16
380    add   eax,dword ptr[cTable+ebx*4]
381
382    add   edx,[LDelta]
383    mov   [edi+4],al
384
385    rol   edx,16
386    mov   [edi+5],ah
387
388    add   ecx,[DeltaVFrac]
389    mov   ah,dl
390
391    sbb   ebx,ebx                         ; U pipe only
392    mov   dh,[esi*2]
393
394    add   ebp,[DeltaUFrac]
395    mov   al,[1+esi*2]
396
397    adc   esi,[4+UVintVfracStepV+ebx*4]      ; U pipe only
398    mov   bl,dh
399
400    mov   eax,dword ptr[cTable+8000h+eax*4]
401    mov   bh,dl
402
403    mov   dh,0
404    and   ebx,0ffffh
405
406    rol   edx,16
407    add   eax,dword ptr[cTable+ebx*4]
408
409    add   edx,[LDelta]
410    mov   [edi+6],al
411
412    rol   edx,16
413    mov   [edi+7],ah
414
415    add   ecx,[DeltaVFrac]
416    mov   ah,dl
417
418    sbb   ebx,ebx                         ; U pipe only
419    mov   dh,[esi*2]
420
421    add   ebp,[DeltaUFrac]
422    mov   al,[1+esi*2]
423
424    adc   esi,[4+UVintVfracStepV+ebx*4]      ; U pipe only
425    mov   bl,dh
426
427    mov   eax,dword ptr[cTable+8000h+eax*4]
428    mov   bh,dl
429
430    mov   dh,0
431    and   ebx,0ffffh
432
433    rol   edx,16
434    add   eax,dword ptr[cTable+ebx*4]
435
436    add   edx,[LDelta]
437    mov   [edi+8],al
438
439    rol   edx,16
440    mov   [edi+9],ah
441
442    add   ecx,[DeltaVFrac]
443    mov   ah,dl
444
445    sbb   ebx,ebx                         ; U pipe only
446    mov   dh,[esi*2]
447
448    add   ebp,[DeltaUFrac]
449    mov   al,[1+esi*2]
450
451    adc   esi,[4+UVintVfracStepV+ebx*4]      ; U pipe only
452    mov   bl,dh
453
454    mov   eax,dword ptr[cTable+8000h+eax*4]
455    mov   bh,dl
456
457    mov   dh,0
458    and   ebx,0ffffh
459
460    rol   edx,16
461    add   eax,dword ptr[cTable+ebx*4]
462
463    add   edx,[LDelta]
464    mov   [edi+10],al
465
466    rol   edx,16
467    mov   [edi+11],ah
468
469    add   ecx,[DeltaVFrac]
470    mov   ah,dl
471
472    sbb   ebx,ebx                         ; U pipe only
473    mov   dh,[esi*2]
474
475    add   ebp,[DeltaUFrac]
476    mov   al,[1+esi*2]
477
478    adc   esi,[4+UVintVfracStepV+ebx*4]      ; U pipe only
479    mov   bl,dh
480
481    mov   eax,dword ptr[cTable+8000h+eax*4]
482    mov   bh,dl
483
484    mov   dh,0
485    and   ebx,0ffffh
486
487    rol   edx,16
488    add   eax,dword ptr[cTable+ebx*4]
489
490    add   edx,[LDelta]
491    mov   [edi+12],al
492
493    rol   edx,16
494    mov   [edi+13],ah
495
496    add   ecx,[DeltaVFrac]
497    mov   ah,dl
498
499    sbb   ebx,ebx                         ; U pipe only
500    mov   dh,[esi*2]
501
502    add   ebp,[DeltaUFrac]
503    mov   al,[1+esi*2]
504
505    adc   esi,[4+UVintVfracStepV+ebx*4]      ; U pipe only
506    mov   bl,dh
507
508    mov   eax,dword ptr[cTable+8000h+eax*4]
509    mov   bh,dl
510
511    mov   dh,0
512    and   ebx,0ffffh
513
514    rol   edx,16
515    add   eax,dword ptr[cTable+ebx*4]
516
517    add   edx,[LDelta]
518    mov   [edi+14],al
519
520    mov   [LVal],edx
521    mov   [edi+15],ah
522
523    pop   ebp
524
525    ; ************** Okay to Access Stack Frame ****************
526    ; ************** Okay to Access Stack Frame ****************
527    ; ************** Okay to Access Stack Frame ****************
528
529
530    ; the fdiv is done, finish right    ; st0  st1  st2  st3  st4  st5  st6  st7
531                                        ; ZR   V/ZR 1/ZR U/ZR UL   VL
532
533    fld     st                          ; ZR   ZR   V/ZR 1/ZR U/ZR UL   VL
534    fmul    st,st(2)                    ; VR   ZR   V/ZR 1/ZR U/ZR UL   VL
535    fxch    st(1)                       ; ZR   VR   V/ZR 1/ZR U/ZR UL   VL
536    fmul    st,st(4)                    ; UR   VR   V/ZR 1/ZR U/ZR UL   VL
537
538    add     edi,16                      ; increment to next span
539    dec     [Subdivisions]              ; decrement span count
540    jnz     whtp_SpanLoop                    ; loop back
541
542whtp_HandleLeftoverPixels:
543
544    mov     esi,pTex
545
546    ; edi = dest dib bits
547    ; esi = texture dib bits
548    ; at this point the FPU contains    ; st0  st1  st2  st3  st4  st5  st6  st7
549    ; inv. means invalid numbers        ; inv. inv. inv. inv. inv. UL   VL
550
551    cmp     [WidthModLength],0          ; are there remaining pixels to draw?
552    jz      whtp_FPUReturn              ; nope, pop the FPU and bail
553
554    mov     ebx,right                   ; get right edge pointer
555
556    ; convert left side coords          ; st0  st1  st2  st3  st4  st5  st6  st7
557
558    fld     st(5)                       ; UL   inv. inv. inv. inv. inv. UL   VL
559    fmul    [FixedScale]                ; UL8 inv. inv. inv. inv. inv. UL   VL
560    fistp   [UFixed]                    ; inv. inv. inv. inv. inv. UL   VL
561
562    fld     st(6)                       ; VL   inv. inv. inv. inv. inv. UL   VL
563    fmul    [FixedScale]                ; VL8 inv. inv. inv. inv. inv. UL   VL
564    fistp   [VFixed]                    ; inv. inv. inv. inv. inv. UL   VL
565
566    cmp     [WidthModLength],1          ; calc how many steps to take
567    jz      whtp_OnePixelSpan           ; just one, don't do deltas
568
569    ; calculate right edge coordinates  ; st0  st1  st2  st3  st4  st5  st6  st7
570    ; r -> R+1
571
572    ; @todo rearrange things so we don't need these two instructions
573    fstp    [FloatTemp]                 ; inv. inv. inv. inv. UL   VL
574    fstp    [FloatTemp]                 ; inv. inv. inv. UL   VL
575
576    //notice the fsubs... hecker doesn't explain this at all (damn him)
577    //These are the compensation for the dudxmodifiers, the fill convention
578    //is left biased so this makes the edge perfect
579
580    fld     [ebx]edgeGrad.VOverZ        ; V/Zr inv. inv. inv. UL   VL
581    fsub    dword ptr grads.dVOverZdX   ; V/ZR inv. inv. inv. UL   VL
582    fld     [ebx]edgeGrad.UOverZ        ; U/Zr V/ZR inv. inv. inv. UL   VL
583    fsub    dword ptr grads.dUOverZdX   ; U/ZR V/ZR inv. inv. inv. UL   VL
584    fld     [ebx]edgeGrad.OneOverZ      ; 1/Zr U/ZR V/ZR inv. inv. inv. UL   VL
585    fsub    dword ptr grads.dOneOverZdX ; 1/ZR U/ZR V/ZR inv. inv. inv. UL   VL
586
587    fdivr   [One]                       ; ZR   U/ZR V/ZR inv. inv. inv. UL   VL
588
589    fmul    st(1),st                    ; ZR   UR   V/ZR inv. inv. inv. UL   VL
590    fmulp   st(2),st                    ; UR   VR   inv. inv. inv. UL   VL
591
592    ; calculate deltas                  ; st0  st1  st2  st3  st4  st5  st6  st7
593
594    fsubr   st(5),st                    ; UR   VR   inv. inv. inv. dU   VL
595    fxch    st(1)                       ; VR   UR   inv. inv. inv. dU   VL
596    fsubr   st(6),st                    ; VR   UR   inv. inv. inv. dU   dV
597    fxch    st(6)                       ; dV   UR   inv. inv. inv. dU   VR
598
599    fidiv   [WidthModLength]            ; dv   UR   inv. inv. inv. dU   VR
600    fmul    [FixedScale]                ; dv8 UR   inv. inv. inv. dU   VR
601    fistp   [DeltaV]                    ; UR   inv. inv. inv. dU   VR
602
603    fxch    st(4)                       ; dU   inv. inv. inv. UR   VR
604    fidiv   [WidthModLength]            ; du   inv. inv. inv. UR   VR
605    fmul    [FixedScale]                ; du8 inv. inv. inv. UR   VR
606    fistp   [DeltaU]                    ; inv. inv. inv. UR   VR
607
608    //this is hecker's klooge for keeping his fpu stack aligned (ught)
609    ; @todo gross!  these are to line up with the other loop
610    fld     st(1)                       ; inv. inv. inv. inv. UR   VR
611    fld     st(2)                       ; inv. inv. inv. inv. inv. UR   VR
612
613whtp_OnePixelSpan:
614
615    mov     esi,[UFixed]                ; get starting coordinates
616    add     esi,dword ptr grads.dUdXModifier
617    mov     ecx,[VFixed]                  ; and v... before ebp gets pushed
618    add     ecx,dword ptr grads.dVdXModifier
619
620    ; leftover pixels loop
621    ; edi = dest dib bits
622    ; esi = texture dib bits
623
624    ; esi = u 16.16
625    ; ecx = v 16.16
626
627    xor     eax,eax
628
629    //this loop isn't too good... didn't get time to tune it well
630    //but it's only for the end of the scanline if there are <8 pixels
631whtp_LeftoverLoop:
632    mov     edx,ecx                     ; copy v
633    mov     ebx,esi
634
635    sar     edx,16                                      ; int(v)
636    add     edi,2
637
638whtp_twidth_log2_patch3:
639    sal     edx,3
640    add     esi,[DeltaU]                ; increment u coordinate
641
642    sar     ebx,16                                      ; int(u)
643    add     edx,pTex
644
645    add     ecx,[DeltaV]                ; increment v coordinate
646    add     ebx,edx
647
648    mov     edx,[LVal]
649    mov     al,byte ptr[1+ebx*2]        ; get source texel
650
651    rol     edx,16
652    mov     bl,byte ptr[ebx*2]
653
654    mov     ah,dl
655    mov     eax,dword ptr[cTable+8000h+eax*4]
656
657    mov     bh,dl
658    and     ebx,0ffffh
659
660    rol     edx,16
661    add     eax,dword ptr[cTable+ebx*4]
662
663    add     edx,[LDelta]
664    mov     [edi-2],al
665
666    mov     [LVal],edx
667    mov     [edi-1],ah
668   
669    dec     [WidthModLength]            ; decrement loop count
670    jnz     whtp_LeftoverLoop                ; finish up
671
672whtp_FPUReturn:
673
674    ; busy FPU registers:               ; st0  st1  st2  st3  st4  st5  st6  st7
675                                        ; xxx  xxx  xxx  xxx  xxx  xxx  xxx
676    ffree   st(0)
677    ffree   st(1)
678    ffree   st(2)
679    ffree   st(3)
680    ffree   st(4)
681    ffree   st(5)
682    ffree   st(6)
683
684whtp_Return:
685
686    fldcw   [OldFPUCW]                  ; restore the FPU
687  }
688}
689#endif
Note: See TracBrowser for help on using the repository browser.