home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / texmap / tmap_per.asm < prev    next >
Assembly Source File  |  1998-06-08  |  33KB  |  1,340 lines

  1. ;THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  2. ;SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
  3. ;END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  4. ;ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  5. ;IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  6. ;SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  7. ;FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  8. ;CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
  9. ;AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
  10. ;COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
  11. ;
  12. ; $Source: f:/miner/source/texmap/rcs/tmap_per.asm $
  13. ; $Revision: 1.26 $
  14. ; $Author: john $
  15. ; $Date: 1995/02/20 18:22:55 $
  16. ;
  17. ; Perspective texture mapper inner loop.
  18. ;
  19. ; $Log: tmap_per.asm $
  20. ; Revision 1.26  1995/02/20  18:22:55  john
  21. ; Put all the externs in the assembly modules into tmap_inc.asm.
  22. ; Also, moved all the C versions of the inner loops into a new module, 
  23. ; scanline.c.
  24. ; Revision 1.25  1995/02/20  17:09:08  john
  25. ; Added code so that you can build the tmapper with no assembly!
  26. ; Revision 1.24  1995/01/10  09:32:07  mike
  27. ; mostly fix garbage at end of scanline, but slow down by 1-4%.
  28. ; Revision 1.23  1994/12/02  23:29:57  mike
  29. ; optimizations.
  30. ; Revision 1.22  1994/11/30  00:57:00  mike
  31. ; optimization.
  32. ; Revision 1.21  1994/11/21  13:57:42  mike
  33. ; fix right side shear bug
  34. ; Revision 1.20  1994/11/12  16:41:09  mike
  35. ; jae -> ja.
  36. ; Revision 1.19  1994/10/27  19:40:00  john
  37. ; Made lighting table lookup be _gr_fade_table[eax] instead
  38. ; of fs:[eax], which gets rig of a segment override that 
  39. ; supposedly costs 1 clock on a 486.  Mainly, I wanted to verify
  40. ; that the only reason we need selectors is for the source texture
  41. ; data .
  42. ; Revision 1.18  1994/05/03  11:08:32  mike
  43. ; Trap divide overflows.
  44. ; Revision 1.17  1994/04/21  15:03:41  mike
  45. ; make faster.
  46. ; Revision 1.16  1994/04/08  16:46:57  john
  47. ; Made 32 fade levels. Hacked.
  48. ; Revision 1.15  1994/03/31  08:35:18  mike
  49. ; Fix quantized-by-4 bug in inner loop.
  50. ; Revision 1.14  1994/03/14  17:41:14  mike
  51. ; Fix bug in unlighted version.
  52. ; Revision 1.13  1994/03/14  15:45:14  mike
  53. ; streamline code.
  54. ; Revision 1.12  1994/01/14  14:01:58  mike
  55. ; *** empty log message ***
  56. ; Revision 1.11  1993/12/18  14:43:44  john
  57. ; Messed around with doing 1/z, the u*(1/z) and v*(1/z)
  58. ; (Went from 23 fps to 21 fps... not good! )
  59. ;
  60. ; Revision 1.10  1993/12/17  16:14:17  john
  61. ; Split lighted/nonlighted, so there is no cmp lighting
  62. ; in the inner loop. 
  63. ; Revision 1.9  1993/12/17  12:34:29  john
  64. ; Made leftover bytes use linear approx instead of correct...
  65. ; should save about 8 divides per scanline on average.
  66. ; Also, took out anti-aliasing code and rearranged to
  67. ; order of some instructions to help on 486 pipelining.
  68. ; (The anti-aliasing code did *not* look good, so I
  69. ; figure there was no reason to keep it in. )
  70. ; Revision 1.8  1993/12/16  18:37:52  mike
  71. ; Align some stuff on 4 byte boundaries.
  72. ; Revision 1.7  1993/11/30  08:44:18  john
  73. ; Made selector set check for < 64*64 bitmaps.
  74. ; Revision 1.6  1993/11/23  17:25:26  john
  75. ; Added safety "and eax, 0fffh" in lighting lookup.
  76. ; Revision 1.5  1993/11/23  15:08:52  mike
  77. ; Fixed lighting bug. 
  78. ; Revision 1.4  1993/11/23  14:38:50  john
  79. ; optimized NORMAL code by switching EBX and ESI, so BH can be used in
  80. ; the lighting process.
  81. ; Revision 1.3  1993/11/23  14:30:53  john
  82. ; Made the perspective tmapper do 1/8 divides; added lighting.
  83. ; Revision 1.2  1993/11/22  10:24:59  mike
  84. ; *** empty log message ***
  85. ; Revision 1.1  1993/09/08  17:29:53  mike
  86. ; Initial revision
  87. ;
  88. ;
  89.  
  90.     .386
  91.  
  92.     public    asm_tmap_scanline_per_
  93.  
  94.     include    tmap_inc.asm
  95.  
  96.     public _max_ecx,_min_ecx
  97.  
  98.  
  99. _DATA    SEGMENT DWORD PUBLIC USE32 'DATA'
  100.     align    4
  101. mem_edx dd ?
  102. ;**_v_window_left    dd    _window_left
  103. ;**_v_window_right    dd    _window_right
  104. ;**_v_window_top    dd    _window_top
  105. ;**_v_window_bottom    dd    _window_bottom
  106.  
  107. ; ---------- These are passed in by the C caller ----------
  108. ; ----------^^ These are passed in by the C caller ^^----------
  109.  
  110.     public    _x,_loop_count, new_end
  111.     align    4
  112. _x    dd    ?
  113. _loop_count    dd    ?
  114.  
  115. _max_ecx    dd    0
  116. _min_ecx    dd    55555555h
  117.  
  118. extern _per2_flag:dword
  119. new_end    dd    1    ; if set, use new, but slower, way of finishing off extra pixels on scanline, 01/10/95 --MK
  120.  
  121.  
  122.     public    _scan_doubling_flag, _linear_if_far_flag
  123.  
  124. _scan_doubling_flag    dd 0
  125. _linear_if_far_flag    dd 0
  126.  
  127. ;---------- local variables
  128.     align    4
  129. req_base    dd    ?
  130. req_size    dd    ?
  131. U0    dd    ?
  132. U1    dd    ?
  133. V0    dd    ?
  134. V1    dd    ?
  135. num_left_over    dd    ?
  136. DU1    dd    ?
  137. DV1    dd    ?
  138. DZ1    dd    ?
  139. ;**_fx_dl_dx1    dd    ?
  140. ;**_fx_dl_dx2    dd    ?
  141.  
  142. _DATA    ENDS
  143.  
  144. DGROUP    GROUP    _DATA
  145.  
  146.  
  147. _TEXT   SEGMENT PARA PUBLIC USE32 'CODE'
  148.     ASSUME    DS:_DATA
  149.     ASSUME    CS:_TEXT
  150.  
  151. ; --------------------------------------------------------------------------------------------------
  152. ; Enter:
  153. ;    _xleft    fixed point left x coordinate
  154. ;    _xright    fixed point right x coordinate
  155. ;    _y    fixed point y coordinate
  156. ;    _pixptr    address of source pixel map
  157. ;    _u    fixed point initial u coordinate
  158. ;    _v    fixed point initial v coordinate
  159. ;    _z    fixed point initial z coordinate
  160. ;    _du_dx    fixed point du/dx
  161. ;    _dv_dx    fixed point dv/dx
  162. ;    _dz_dx    fixed point dz/dx
  163.  
  164. ;   for (x = (int) xleft; x <= (int) xright; x++) {
  165. ;      _setcolor(read_pixel_from_tmap(srcb,((int) (u/z)) & 63,((int) (v/z)) & 63));
  166. ;      _setpixel(x,y);
  167. ;
  168. ;      u += du_dx;
  169. ;      v += dv_dx;
  170. ;      z += dz_dx;
  171. ;   }
  172.  
  173.  
  174. ;;goto_none_to_do:
  175. ;; int 3    ; thinking this can't get hit, if so, kill compare against _window_bottom
  176. ;; jmp _none_to_do
  177.     align    16
  178. asm_tmap_scanline_per_:
  179.     push    es
  180.     pusha
  181.     
  182. ;---------------------------- setup for loop ---------------------------------
  183. ; Setup for loop:    _loop_count  iterations = (int) xright - (int) xleft
  184. ;    esi    source pixel pointer = pixptr
  185. ;    edi    initial row pointer = y*320+x
  186. ; NOTE: fx_xright and fx_xleft changed from fix to int by mk on 12/01/94.
  187.  
  188. ; set esi = pointer to start of texture map data
  189.  
  190. ; set edi = address of first pixel to modify
  191.     mov    edi,_fx_y
  192.     mov    es,_pixel_data_selector    ; selector[0*2]
  193. ;;    cmp    edi,_window_bottom
  194. ;;    ja    goto_none_to_do
  195.  
  196.     mov    edi,_y_pointers[edi*4]
  197.  
  198.     mov    ebx,_fx_xleft
  199.     test    ebx, ebx
  200.     jns    ebx_ok
  201.     xor    ebx, ebx
  202. ebx_ok:    add    edi,write_buffer
  203.     add    edi,ebx
  204.  
  205. ; set _loop_count = # of iterations
  206.     mov    eax,_fx_xright
  207. ;;    cmp    eax,_window_right
  208. ;;    jl    eax_ok1
  209. ;;    mov    eax,_window_right
  210. ;;eax_ok1:
  211. ;;    cmp    eax,_window_left
  212. ;;    jg    eax_ok2
  213. ;;    mov    eax,_window_left
  214. ;;eax_ok2:
  215.     sub    eax,ebx
  216.     js    _none_to_do
  217. ;;    cmp    eax,_window_width
  218. ;;    jbe    _ok_to_do
  219. ;;    mov    eax,_window_width
  220. ;;_ok_to_do:
  221.     mov    _loop_count,eax
  222.  
  223. ; lighting values are passed in fixed point, but need to be in 8 bit integer, 8 bit fraction so we can easily
  224. ; get the integer by reading %bh
  225.     sar    _fx_l, 8
  226.     sar    _fx_dl_dx,8
  227.     jns    dl_dx_ok
  228.     inc    _fx_dl_dx    ; round towards 0 for negative deltas
  229. dl_dx_ok:
  230.  
  231. ; set initial values
  232.     mov    ebx,_fx_u
  233.     mov    ebp,_fx_v
  234.     mov    ecx,_fx_z
  235.  
  236.     test    _per2_flag,-1
  237.     je    tmap_loop
  238.  
  239.     test    _Lighting_on, -1
  240.     je    tmap_loop_fast_nolight
  241.     jmp    tmap_loop_fast
  242.  
  243. ;================ PERSPECTIVE TEXTURE MAP INNER LOOPS ========================
  244. ;
  245. ; Usage in loop:    eax    division, pixel value
  246. ;    ebx    u
  247. ;    ecx    z
  248. ;    edx    division
  249. ;    ebp    v
  250. ;    esi    source pixel pointer
  251. ;    edi    destination pixel pointer
  252.  
  253. ;-------------------- NORMAL PERSPECTIVE TEXTURE MAP LOOP -----------------
  254. tmap_loop:
  255.     mov    esi, ebx    ; esi becomes u coordinate
  256.  
  257.     align    4
  258. tmap_loop0:
  259.  
  260. ; compute v coordinate
  261.     mov    eax, ebp    ; get v
  262.     mov    edx, eax
  263.     sar    edx, 31
  264.     idiv    ecx    ; eax = (v/z)
  265.  
  266.     and    eax,3fh    ; mask with height-1
  267.     mov    ebx,eax
  268.  
  269. ; compute u coordinate
  270.     mov    eax, esi    ; get u
  271.     mov    edx, eax
  272.     sar    edx, 31
  273.     idiv    ecx    ; eax = (u/z)
  274.  
  275.     shl     eax,26
  276.     shld     ebx,eax,6    ; esi = v*64+u
  277.  
  278. ; read 1 pixel
  279.     xor    eax, eax
  280.     test    _Lighting_on, -1
  281.     mov    al, es:[ebx]    ; get pixel from source bitmap
  282.     je    NoLight1
  283.  
  284. ; LIGHTING CODE
  285.     mov    ebx, _fx_l    ; get temp copy of lighting value
  286.     mov    ah, bh    ; get lighting level
  287.     add    ebx, _fx_dl_dx    ; update lighting value
  288.     mov    al, _gr_fade_table[eax]    ; xlat pixel thru lighting tables
  289.     mov    _fx_l, ebx    ; save temp copy of lighting value
  290.  
  291. ; transparency check
  292. NoLight1:    cmp    al,255
  293.     je    skip1
  294.  
  295.     mov    [edi],al
  296. skip1:    inc    edi
  297.     
  298. ; update deltas
  299.     add    ebp,_fx_dv_dx
  300.     add    esi,_fx_du_dx
  301.     add    ecx,_fx_dz_dx
  302.     je    _div_0_abort    ; would be dividing by 0, so abort
  303.  
  304.     dec    _loop_count
  305.     jns    tmap_loop0
  306.  
  307. _none_to_do:    
  308.     popa
  309.     pop    es
  310.     ret
  311.  
  312. ; We detected a z=0 condition, which seems pretty bogus, don't you think?
  313. ; So, we abort, but maybe we want to know about it.
  314. _div_0_abort:
  315. ;**    int    3
  316.     jmp    _none_to_do
  317.  
  318. ;-------------------------- PER/4 TMAPPER ----------------
  319. ;    x = x1
  320. ;    U0 = u/w; V0 = v/w;
  321. ;    while ( 1 )
  322. ;        u += du_dx*4; v+= dv_dx*4
  323. ;        U1 = u/w; V1 = v/w;
  324. ;        DUDX = (U1-U0)/4; DVDX = (V1-V0)/4;
  325. ;
  326. ;    ; Pixel 0
  327. ;        pixels = texmap[V0*64+U0];
  328. ;        U0 += DUDX; V0 += DVDX
  329. ;    ; Pixel 1
  330. ;        pixels = (pixels<<8)+texmap[V0*64+U0];
  331. ;        U0 += DUDX; V0 += DVDX
  332. ;    ; Pixel 2
  333. ;        pixels = (pixels<<8)+texmap[V0*64+U0];
  334. ;        U0 += DUDX; V0 += DVDX
  335. ;    ; Pixel 3
  336. ;        pixels = (pixels<<8)+texmap[V0*64+U0];
  337. ;
  338. ;        screen[x] = pixel
  339. ;        x += 4;
  340. ;        U0 = U1; V0 = V1 
  341.  
  342. NBITS = 4    ; 2^NBITS pixels plotted per divide
  343. ZSHIFT = 4    ; precision used in PDIV macro
  344.  
  345.  
  346. PDIV MACRO
  347. ; Returns EAX/ECX in 16.16 format in EAX. Trashes EDX
  348. ;          sig bits   6.3
  349.     mov    edx,eax
  350.     shl    eax,ZSHIFT
  351.     sar    edx,32-ZSHIFT
  352.     idiv    ecx    ; eax = (v/z)
  353.     shl    eax, 16-ZSHIFT
  354.  
  355. ENDM
  356.  
  357. wr_onepix    macro    num
  358.     local    skip
  359.     cmp    cl,255
  360.     je    skip
  361.     mov    num[edi],cl
  362. skip:    ror    ecx,8
  363.  
  364.     endm
  365.  
  366. public tmap_loop_fast
  367.  
  368. ; -------------------------------------- Start of Getting Dword Aligned ----------------------------------------------
  369. ;    ebx    fx_u
  370.  
  371. tmap_loop_fast:
  372.     mov    esi,ebx
  373.  
  374.     align    4
  375. NotDwordAligned1:
  376.     test    edi, 11b
  377.     jz    DwordAligned1
  378.  
  379. ; compute v coordinate
  380.     mov    eax, ebp    ; get v
  381.     mov    edx, eax
  382.     sar    edx, 31
  383.     idiv    ecx    ; eax = (v/z)
  384.  
  385.     and    eax,3fh    ; mask with height-1
  386.     mov    ebx,eax
  387.  
  388. ; compute u coordinate
  389.     mov    eax, esi    ; get u
  390.     mov    edx, eax
  391.     sar    edx, 31
  392.     idiv    ecx    ; eax = (u/z)
  393.  
  394.     shl     eax,26
  395.     shld     ebx,eax,6    ; esi = v*64+u
  396.  
  397. ; read 1  pixel
  398.     xor    eax, eax
  399.     mov    al, es:[ebx]    ; get pixel from source bitmap
  400.  
  401. ; lighting code
  402.     mov    ebx, _fx_l    ; get temp copy of lighting value
  403.     mov    ah, bh    ; get lighting level
  404.     add    ebx, _fx_dl_dx    ; update lighting value
  405.     mov    _fx_l, ebx    ; save temp copy of lighting value
  406.  
  407. ; transparency check
  408.     cmp    al,255
  409.     je    skip2    ; this pixel is transparent, so don't write it (or light it)
  410.  
  411.     mov    al, _gr_fade_table[eax]    ; xlat pixel thru lighting tables
  412.                     
  413. ; write 1 pixel
  414.     mov    [edi],al
  415. skip2:    inc    edi
  416.     
  417. ; update deltas
  418.     add    ebp,_fx_dv_dx
  419.     add    esi,_fx_du_dx
  420.     add    ecx,_fx_dz_dx
  421.     je    _div_0_abort    ; would be dividing by 0, so abort
  422.  
  423.     dec    _loop_count
  424.     jns    NotDwordAligned1
  425.  
  426.     jmp    _none_to_do
  427.  
  428. ; -------------------------------------- End of Getting Dword Aligned ----------------------------------------------
  429.  
  430. DwordAligned1:
  431.  
  432. ;--;    mov    ebx,esi    ; get fx_u
  433. ;--;
  434. ;--;    mov    eax, _loop_count
  435. ;--;    inc    eax
  436. ;--;    mov    num_left_over, eax
  437. ;--;    shr    eax, NBITS
  438. ;--;
  439. ;--;    test    eax, -1
  440. ;--;    je    tmap_loop    ; there are no 2^NBITS chunks, do divide/pixel for whole scanline
  441. ;--;    
  442. ;--;    mov     _loop_count, eax    ; _loop_count = pixels / NPIXS
  443. ;--;    shl    eax, NBITS
  444. ;--;    sub    num_left_over, eax    ; num_left_over = obvious
  445.  
  446.     mov    eax, _loop_count
  447.     mov    ebx, esi    ; get fx_u [pentium pipelining]
  448.     inc    eax
  449.     mov    esi, eax
  450.     and    esi, (1 shl NBITS) - 1
  451.     sar    eax, NBITS
  452.     mov    num_left_over, esi
  453.     je    tmap_loop    ; there are no 2^NBITS chunks, do divide/pixel for whole scanline
  454.     mov     _loop_count, eax    ; _loop_count = pixels / NPIXS
  455.         
  456. ; compute initial v coordinate
  457.     mov    eax,ebp    ; get v
  458.     mov    edx,ebp
  459.     shl    eax,ZSHIFT
  460.     sar    edx,32-ZSHIFT
  461.     idiv    ecx    ; eax = (v/z)
  462.     shl    eax, 16-ZSHIFT
  463.     mov    V0, eax
  464.  
  465. ; compute initial u coordinate
  466.     mov    eax,ebx    ; get u
  467.     mov    edx,ebx
  468.     shl    eax,ZSHIFT
  469.     sar    edx,32-ZSHIFT
  470.     idiv    ecx    ; eax = (v/z)
  471.     shl    eax, 16-ZSHIFT
  472.     mov    U0, eax
  473.  
  474. ; Set deltas to NPIXS pixel increments
  475.     mov    eax, _fx_du_dx
  476.     shl    eax, NBITS
  477.     mov    DU1, eax
  478.     mov    eax, _fx_dv_dx
  479.     shl    eax, NBITS
  480.     mov    DV1, eax
  481.     mov    eax, _fx_dz_dx
  482.     shl    eax, NBITS
  483.     mov    DZ1, eax
  484.  
  485.     align    4
  486. TopOfLoop4:
  487.     add    ebx, DU1
  488.     add    ebp, DV1
  489.     add    ecx, DZ1
  490.     je    _div_0_abort    ; would be dividing by 0, so abort
  491.  
  492. ; Done with ebx, ebp, ecx until next iteration
  493.     push    ebx
  494.     push    ecx
  495.     push    ebp
  496.     push    edi
  497.     
  498. ; Find fixed U1        
  499.     mov    eax, ebx
  500.     mov    edx,ebx
  501.     shl    eax,ZSHIFT
  502.     sar    edx,32-ZSHIFT
  503.     idiv    ecx    ; eax = (v/z)
  504.     shl    eax, 16-ZSHIFT
  505.     mov    ebx, eax    ; ebx = U1 until pop's
  506.  
  507. ; Find fixed V1        
  508.     mov    eax, ebp
  509.     mov    edx, ebp
  510.     shl    eax,ZSHIFT
  511.     sar    edx,32-ZSHIFT
  512.     idiv    ecx    ; eax = (v/z)
  513.  
  514.     mov    ecx, U0    ; ecx = U0 until pop's
  515.     mov    edi, V0    ; edi = V0 until pop's
  516.  
  517.     shl    eax, 16-ZSHIFT
  518.     mov    ebp, eax    ; ebp = V1 until pop's
  519.  
  520. ; Make ESI =  V0:U0 in 6:10,6:10 format
  521.     mov    eax, ecx
  522.     shr    eax, 6
  523.     mov    esi, edi
  524.     shl    esi, 10
  525.     mov    si, ax
  526.         
  527. ; Make EDX = DV:DU in 6:10,6:10 format
  528.     mov    eax, ebx
  529.     sub    eax, ecx
  530.     sar    eax, NBITS+6
  531.     mov    edx, ebp
  532.     sub    edx, edi
  533.     shl    edx, 10-NBITS    ; EDX = V1-V0/ 4 in 6:10 int:frac
  534.     mov    dx, ax    ; put delta u in low word
  535.  
  536. ; Save the U1 and V1 so we don't have to divide on the next iteration
  537.     mov    U0, ebx
  538.     mov    V0, ebp
  539.  
  540.     pop    edi    ; Restore EDI before using it
  541.         
  542. ; LIGHTING CODE
  543.     mov    ebx, _fx_l
  544.     mov    ebp, _fx_dl_dx
  545.  
  546.     test    _transparency_on,-1
  547.     je    no_trans1
  548.  
  549.     REPT (1 SHL (NBITS-2))
  550.     local    skip3,no_trans1
  551.         REPT 2
  552.     local    skipa1,skipa2
  553.  
  554.     mov    eax, esi    ; get u,v
  555.     shr    eax, 26    ; shift out all but int(v)
  556.     shld    ax,si,6    ; shift in u, shifting up v
  557.     add    esi, edx    ; inc u,v
  558.     mov     al, es:[eax]    ; get pixel from source bitmap
  559.     cmp    al,255
  560.     je    skipa1
  561.     mov    ah, bh    ; form lighting table lookup value
  562.     add    ebx, ebp    ; update lighting value
  563.     mov    al, _gr_fade_table[eax]    ; xlat thru lighting table into dest buffer
  564.     mov    [edi],al
  565. skipa1:
  566.     inc    edi
  567.  
  568. ; Do odd pixel
  569.     mov    eax, esi    ; get u,v
  570.     shr    eax, 26    ; shift out all but int(v)
  571.     shld    ax,si,6    ; shift in u, shifting up v
  572.     add    esi, edx    ; inc u,v
  573.     mov     al, es:[eax]    ; get pixel from source bitmap
  574.     cmp    al,255
  575.     je    skipa2
  576.     mov    ah, bh    ; form lighting table lookup value
  577.     add    ebx, ebp    ; update lighting value
  578.     mov    al, _gr_fade_table[eax]    ; xlat thru lighting table into dest buffer
  579.     mov    [edi],al
  580. skipa2:
  581.     inc    edi
  582.  
  583.         ENDM
  584.  
  585.     ENDM
  586.     jmp    cont1
  587.  
  588. ; -------------------------------------------------------
  589. no_trans1:
  590. ;----------; push edx
  591. ;----------; mov mem_edx, edx
  592. ;----------; sub edx, edx
  593.   REPT (1 SHL (NBITS-2))
  594.     REPT 2
  595.  
  596.     mov    eax, esi    ; get u,v
  597.     shr    eax, 26    ; shift out all but int(v)
  598.     shld    ax,si,6    ; shift in u, shifting up v
  599.     add    esi, edx    ; inc u,v
  600.     mov     al, es:[eax]    ; get pixel from source bitmap
  601.     mov    ah, bh    ; form lighting table lookup value
  602.     add    ebx, ebp    ; update lighting value
  603.     mov    cl, _gr_fade_table[eax]    ; xlat thru lighting table into dest buffer
  604.  
  605. ; Do odd pixel
  606.     mov    eax, esi    ; get u,v
  607.     shr    eax, 26    ; shift out all but int(v)
  608.     shld    ax,si,6    ; shift in u, shifting up v
  609.     add    esi, edx    ; inc u,v
  610.     mov     al, es:[eax]    ; get pixel from source bitmap
  611.     mov    ah, bh    ; form lighting table lookup value
  612.     add    ebx, ebp    ; update lighting value
  613.     mov    ch, _gr_fade_table[eax]    ; xlat thru lighting table into dest buffer
  614.  
  615. ; ----- This is about 1% faster than the above, and could probably be optimized more.
  616. ; ----- Problem is, it gets the u,v coordinates backwards.  What you would need to do
  617. ; ----- is switch the packing of the u,v coordinates above (about 95 lines up).
  618. ;----------;    mov    eax, esi
  619. ;----------;    shr    ax, 10
  620. ;----------;    rol    eax, 6
  621. ;----------;    mov    dx, ax
  622. ;----------;    add    esi, mem_edx
  623. ;----------;    mov    dl, es:[edx]
  624. ;----------;    mov    dh, bh
  625. ;----------;    add    ebx, ebp
  626. ;----------;    mov    cl, _gr_fade_table[edx]
  627. ;----------;
  628. ;----------;    mov    eax, esi
  629. ;----------;    shr    ax, 10
  630. ;----------;    rol    eax, 6
  631. ;----------;    mov    dx, ax
  632. ;----------;    add    esi, mem_edx
  633. ;----------;    mov    dl, es:[edx]
  634. ;----------;    mov    dh, bh
  635. ;----------;    add    ebx, ebp
  636. ;----------;    mov    ch, _gr_fade_table[edx]
  637.  
  638.     ror    ecx, 16    ; move to next double dest pixel position
  639.  
  640.     ENDM
  641.     mov     [edi],ecx    ; Draw 4 pixels to display
  642.     add     edi,4
  643.   ENDM
  644. ;; pop edx
  645. cont1:
  646.  
  647. ; -------------------------------------------------------
  648.  
  649. ; LIGHTING CODE
  650.     mov    _fx_l, ebx
  651.     pop    ebp
  652.     pop    ecx
  653.     pop    ebx
  654.     dec    _loop_count
  655.     jnz    TopOfLoop4
  656.  
  657. EndOfLoop4:
  658.     test    num_left_over, -1
  659.     je    _none_to_do
  660.  
  661. ; ----------------------------------------- Start of LeftOver Pixels ------------------------------------------
  662. DoEndPixels:
  663.     push    ecx
  664.  
  665.     mov    eax, ecx
  666.     lea    eax, [eax*2+eax]
  667.  
  668.     add    ecx, DZ1
  669.     js    notokhere
  670.     shl    ecx,2
  671.     cmp    eax, ecx
  672.     pop    ecx
  673.     jl    okhere
  674.     jmp    bah_bah
  675. notokhere:
  676.     pop    ecx
  677. bah_bah:
  678.     test    new_end,-1
  679.     jne    NewDoEndPixels
  680. okhere:
  681.  
  682.     add    ebx, DU1
  683.     add    ebp, DV1
  684.     add    ecx, DZ1
  685.     je    _div_0_abort
  686.     jns    dep_cont
  687.  
  688. ; z went negative.
  689. ; this can happen because we added DZ1 to the current z, but dz1 represents dz for perhaps 16 pixels
  690. ; though we might only plot one more pixel.
  691.     mov    cl, 1
  692.  
  693. dep_loop:    mov    eax, DU1
  694.     sar    eax, cl
  695.     sub    ebx, eax
  696.  
  697.     mov    eax, DV1
  698.     sar    eax, cl
  699.     sub    ebp, eax
  700.  
  701.     mov    eax, DZ1
  702.     sar    eax, cl
  703.     sub    ecx, eax
  704.     je    _div_0_abort
  705.     jns    dep_cont
  706.  
  707.     inc    cl
  708.     cmp    cl, NBITS
  709.     jne    dep_loop
  710.  
  711. dep_cont:
  712.     push    edi    ; use edi as a temporary variable
  713.  
  714.     cmp    ecx,1 shl (ZSHIFT+1)
  715.     jg    ecx_ok
  716.     mov    ecx, 1 shl (ZSHIFT+1)
  717. ecx_ok:
  718.  
  719. ; Find fixed U1        
  720.     mov    eax, ebx
  721.     PDIV
  722.     mov    ebx, eax    ; ebx = U1 until pop's
  723.  
  724. ; Find fixed V1        
  725.     mov    eax, ebp
  726.     PDIV
  727.     mov    ebp, eax    ; ebp = V1 until pop's
  728.  
  729.     mov    ecx, U0    ; ecx = U0 until pop's
  730.     mov    edi, V0    ; edi = V0 until pop's
  731.  
  732. ; Make ESI =  V0:U0 in 6:10,6:10 format
  733.     mov    eax, ecx
  734.     shr    eax, 6
  735.     mov    esi, edi
  736.     shl    esi, 10
  737.     mov    si, ax
  738.         
  739. ; Make EDX = DV:DU in 6:10,6:10 format
  740.     mov    eax, ebx
  741.     sub    eax, ecx
  742.     sar    eax, NBITS+6
  743.     mov    edx, ebp
  744.     sub    edx, edi
  745.     shl    edx, 10-NBITS    ; EDX = V1-V0/ 4 in 6:10 int:frac
  746.     mov    dx, ax    ; put delta u in low word
  747.  
  748.     pop    edi    ; Restore EDI before using it
  749.         
  750.     mov    ecx, num_left_over
  751.  
  752. ; LIGHTING CODE
  753.     mov    ebx, _fx_l
  754.     mov    ebp, _fx_dl_dx
  755.  
  756.     ITERATION = 0
  757.     REPT (1 SHL (NBITS-1))
  758.     local    skip4, skip5
  759. ; Do even pixel
  760.     mov    eax, esi    ; get u,v
  761.     shr    eax, 26    ; shift out all but int(v)
  762.     shld    ax,si,6    ; shift in u, shifting up v
  763.     mov     al, es:[eax]    ; get pixel from source bitmap
  764.     add    esi, edx    ; inc u,v
  765.     mov    ah, bh    ; form lighting table lookup value
  766.     add    ebx, ebp    ; update lighting value
  767.     cmp    al,255
  768.     je    skip4
  769.     mov    al, _gr_fade_table[eax]    ; xlat thru lighting table into dest buffer
  770.     mov    [edi+ITERATION], al    ; write pixel
  771. skip4:    dec    ecx
  772.     jz    _none_to_do
  773.     ITERATION = ITERATION + 1
  774.  
  775. ; Do odd pixel
  776.     mov    eax, esi    ; get u,v
  777.     shr    eax, 26    ; shift out all but int(v)
  778.     shld    ax,si,6    ; shift in u, shifting up v
  779.     mov     al, es:[eax]    ; get pixel from source bitmap
  780.     add    esi, edx    ; inc u,v
  781.     mov    ah, bh    ; form lighting table lookup value
  782.     add    ebx, _fx_dl_dx    ; update lighting value
  783.     cmp    al,255
  784.     je    skip5
  785.     mov    al, _gr_fade_table[eax]    ; xlat thru lighting table into dest buffer
  786.     mov    [edi+ITERATION], al    ; write pixel
  787. skip5:    dec    ecx
  788.     jz    _none_to_do
  789.     ITERATION = ITERATION + 1
  790.     ENDM
  791.  
  792. ; Should never get here!!!!
  793.     int    3
  794.     jmp    _none_to_do
  795.  
  796. ; ----------------------------------------- End of LeftOver Pixels ------------------------------------------
  797.  
  798. ; --BUGGY NEW--NewDoEndPixels:
  799. ; --BUGGY NEW--    mov    eax, num_left_over
  800. ; --BUGGY NEW--    and    num_left_over, 3
  801. ; --BUGGY NEW--    shr    eax, 2
  802. ; --BUGGY NEW--    je    NDEP_1
  803. ; --BUGGY NEW--    mov    _loop_count, eax
  804. ; --BUGGY NEW--
  805. ; --BUGGY NEW--; do 4 pixels per hunk, not 16, so div deltas by 4 (16/4=4)
  806. ; --BUGGY NEW-- shr DU1,2
  807. ; --BUGGY NEW-- shr DV1,2
  808. ; --BUGGY NEW-- shr DZ1,2
  809. ; --BUGGY NEW--
  810. ; --BUGGY NEW--NDEP_TopOfLoop4:
  811. ; --BUGGY NEW--    add    ebx, DU1
  812. ; --BUGGY NEW--    add    ebp, DV1
  813. ; --BUGGY NEW--    add    ecx, DZ1
  814. ; --BUGGY NEW--    je    _div_0_abort    ; would be dividing by 0, so abort
  815. ; --BUGGY NEW--
  816. ; --BUGGY NEW--; Done with ebx, ebp, ecx until next iteration
  817. ; --BUGGY NEW--    push    ebx
  818. ; --BUGGY NEW--    push    ecx
  819. ; --BUGGY NEW--    push    ebp
  820. ; --BUGGY NEW--    push    edi
  821. ; --BUGGY NEW--    
  822. ; --BUGGY NEW--; Find fixed U1        
  823. ; --BUGGY NEW--    mov    eax, ebx
  824. ; --BUGGY NEW--    mov    edx,ebx
  825. ; --BUGGY NEW--    shl    eax,(ZSHIFT-2)
  826. ; --BUGGY NEW--    sar    edx,32-(ZSHIFT-2)
  827. ; --BUGGY NEW--    idiv    ecx    ; eax = (v/z)
  828. ; --BUGGY NEW--    shl    eax, 16-(ZSHIFT-2)
  829. ; --BUGGY NEW--    mov    ebx, eax    ; ebx = U1 until pop's
  830. ; --BUGGY NEW--
  831. ; --BUGGY NEW--; Find fixed V1        
  832. ; --BUGGY NEW--    mov    eax, ebp
  833. ; --BUGGY NEW--    mov    edx, ebp
  834. ; --BUGGY NEW--    shl    eax,(ZSHIFT-2)
  835. ; --BUGGY NEW--    sar    edx,32-(ZSHIFT-2)
  836. ; --BUGGY NEW--    idiv    ecx    ; eax = (v/z)
  837. ; --BUGGY NEW--
  838. ; --BUGGY NEW--    mov    ecx, U0    ; ecx = U0 until pop's
  839. ; --BUGGY NEW--    mov    edi, V0    ; edi = V0 until pop's
  840. ; --BUGGY NEW--
  841. ; --BUGGY NEW--    shl    eax, 16-(ZSHIFT-2)
  842. ; --BUGGY NEW--    mov    ebp, eax    ; ebp = V1 until pop's
  843. ; --BUGGY NEW--
  844. ; --BUGGY NEW--; Make ESI =  V0:U0 in 6:10,6:10 format
  845. ; --BUGGY NEW--    mov    eax, ecx
  846. ; --BUGGY NEW--    shr    eax, 6
  847. ; --BUGGY NEW--    mov    esi, edi
  848. ; --BUGGY NEW--    shl    esi, 10
  849. ; --BUGGY NEW--    mov    si, ax
  850. ; --BUGGY NEW--
  851. ; --BUGGY NEW--; Make EDX = DV:DU in 6:10,6:10 format
  852. ; --BUGGY NEW--    mov    eax, ebx
  853. ; --BUGGY NEW--    sub    eax, ecx
  854. ; --BUGGY NEW--    sar    eax, (NBITS-2)+6
  855. ; --BUGGY NEW--    mov    edx, ebp
  856. ; --BUGGY NEW--    sub    edx, edi
  857. ; --BUGGY NEW--    shl    edx, 10-(NBITS-2)    ; EDX = V1-V0/ 4 in 6:10 int:frac
  858. ; --BUGGY NEW--    mov    dx, ax    ; put delta u in low word
  859. ; --BUGGY NEW--
  860. ; --BUGGY NEW--; Save the U1 and V1 so we don't have to divide on the next iteration
  861. ; --BUGGY NEW--    mov    U0, ebx
  862. ; --BUGGY NEW--    mov    V0, ebp
  863. ; --BUGGY NEW--
  864. ; --BUGGY NEW--    pop    edi    ; Restore EDI before using it
  865. ; --BUGGY NEW--        
  866. ; --BUGGY NEW--; LIGHTING CODE
  867. ; --BUGGY NEW--    mov    ebx, _fx_l
  868. ; --BUGGY NEW--    mov    ebp, _fx_dl_dx
  869. ; --BUGGY NEW--
  870. ; --BUGGY NEW--;**    test    _transparency_on,-1
  871. ; --BUGGY NEW--;**    je    NDEP_no_trans1
  872. ; --BUGGY NEW--
  873. ; --BUGGY NEW--        REPT 2
  874. ; --BUGGY NEW--    local    NDEP_skipa1, NDEP_skipa2
  875. ; --BUGGY NEW--
  876. ; --BUGGY NEW--    mov    eax, esi    ; get u,v
  877. ; --BUGGY NEW--    shr    eax, 26    ; shift out all but int(v)
  878. ; --BUGGY NEW--    shld    ax,si,6    ; shift in u, shifting up v
  879. ; --BUGGY NEW--    add    esi, edx    ; inc u,v
  880. ; --BUGGY NEW--    mov     al, es:[eax]    ; get pixel from source bitmap
  881. ; --BUGGY NEW--    cmp    al,255
  882. ; --BUGGY NEW--    je    NDEP_skipa1
  883. ; --BUGGY NEW--    mov    ah, bh    ; form lighting table lookup value
  884. ; --BUGGY NEW--    add    ebx, ebp    ; update lighting value
  885. ; --BUGGY NEW--    mov    al, _gr_fade_table[eax]    ; xlat thru lighting table into dest buffer
  886. ; --BUGGY NEW--    mov    [edi],al
  887. ; --BUGGY NEW--NDEP_skipa1:
  888. ; --BUGGY NEW--    inc    edi
  889. ; --BUGGY NEW--
  890. ; --BUGGY NEW--; Do odd pixel
  891. ; --BUGGY NEW--    mov    eax, esi    ; get u,v
  892. ; --BUGGY NEW--    shr    eax, 26    ; shift out all but int(v)
  893. ; --BUGGY NEW--    shld    ax,si,6    ; shift in u, shifting up v
  894. ; --BUGGY NEW--    add    esi, edx    ; inc u,v
  895. ; --BUGGY NEW--    mov     al, es:[eax]    ; get pixel from source bitmap
  896. ; --BUGGY NEW--    cmp    al,255
  897. ; --BUGGY NEW--    je    NDEP_skipa2
  898. ; --BUGGY NEW--    mov    ah, bh    ; form lighting table lookup value
  899. ; --BUGGY NEW--    add    ebx, ebp    ; update lighting value
  900. ; --BUGGY NEW--    mov    al, _gr_fade_table[eax]    ; xlat thru lighting table into dest buffer
  901. ; --BUGGY NEW--    mov    [edi],al
  902. ; --BUGGY NEW--NDEP_skipa2:
  903. ; --BUGGY NEW--    inc    edi
  904. ; --BUGGY NEW--
  905. ; --BUGGY NEW--        ENDM
  906. ; --BUGGY NEW--
  907. ; --BUGGY NEW--    mov    _fx_l, ebx
  908. ; --BUGGY NEW--    pop    ebp
  909. ; --BUGGY NEW--    pop    ecx
  910. ; --BUGGY NEW--    pop    ebx
  911. ; --BUGGY NEW--    dec    _loop_count
  912. ; --BUGGY NEW--    jnz    NDEP_TopOfLoop4
  913. ; --BUGGY NEW--
  914. ; --BUGGY NEW--    test    num_left_over, -1
  915. ; --BUGGY NEW--    je    _none_to_do
  916. ; --BUGGY NEW--
  917. ; --BUGGY NEW--NDEP_1:
  918. ; --BUGGY NEW--    mov    esi,ebx
  919. ; --BUGGY NEW--
  920. ; --BUGGY NEW--    align    4
  921. ; --BUGGY NEW--NDEP_loop:
  922. ; --BUGGY NEW--
  923. ; --BUGGY NEW--; compute v coordinate
  924. ; --BUGGY NEW--    mov    eax, ebp    ; get v
  925. ; --BUGGY NEW--    mov    edx, eax
  926. ; --BUGGY NEW--    sar    edx, 31
  927. ; --BUGGY NEW--    idiv    ecx    ; eax = (v/z)
  928. ; --BUGGY NEW--
  929. ; --BUGGY NEW--    and    eax,3fh    ; mask with height-1
  930. ; --BUGGY NEW--    mov    ebx,eax
  931. ; --BUGGY NEW--
  932. ; --BUGGY NEW--; compute u coordinate
  933. ; --BUGGY NEW--    mov    eax,     esi    ; get u
  934. ; --BUGGY NEW--    mov    edx, eax
  935. ; --BUGGY NEW--    sar    edx, 31
  936. ; --BUGGY NEW--    idiv    ecx    ; eax = (u/z)
  937. ; --BUGGY NEW--
  938. ; --BUGGY NEW--    shl     eax,26
  939. ; --BUGGY NEW--    shld     ebx,eax,6    ; esi = v*64+u
  940. ; --BUGGY NEW--
  941. ; --BUGGY NEW--; read 1  pixel
  942. ; --BUGGY NEW--    xor    eax, eax
  943. ; --BUGGY NEW--    mov    al, es:[ebx]    ; get pixel from source bitmap
  944. ; --BUGGY NEW--
  945. ; --BUGGY NEW--; lighting code
  946. ; --BUGGY NEW--    mov    ebx, _fx_l    ; get temp copy of lighting value
  947. ; --BUGGY NEW--    mov    ah, bh    ; get lighting level
  948. ; --BUGGY NEW--    add    ebx, _fx_dl_dx    ; update lighting value
  949. ; --BUGGY NEW--    mov    _fx_l, ebx    ; save temp copy of lighting value
  950. ; --BUGGY NEW--
  951. ; --BUGGY NEW--; transparency check
  952. ; --BUGGY NEW--    cmp    al,255
  953. ; --BUGGY NEW--    je    NDEP_skip2    ; this pixel is transparent, so don't write it (or light it)
  954. ; --BUGGY NEW--
  955. ; --BUGGY NEW--    mov    al, _gr_fade_table[eax]    ; xlat pixel thru lighting tables
  956. ; --BUGGY NEW--                    
  957. ; --BUGGY NEW--; write 1 pixel
  958. ; --BUGGY NEW--    mov    [edi],al
  959. ; --BUGGY NEW--NDEP_skip2:    inc    edi
  960. ; --BUGGY NEW--    
  961. ; --BUGGY NEW--; update deltas
  962. ; --BUGGY NEW--    add    ebp,_fx_dv_dx
  963. ; --BUGGY NEW--    add    esi,_fx_du_dx
  964. ; --BUGGY NEW--    add    ecx,_fx_dz_dx
  965. ; --BUGGY NEW--    je    _div_0_abort    ; would be dividing by 0, so abort
  966. ; --BUGGY NEW--
  967. ; --BUGGY NEW--    dec    num_left_over
  968. ; --BUGGY NEW--    jne    NDEP_loop
  969. ; --BUGGY NEW--
  970. ; --BUGGY NEW--    jmp    _none_to_do
  971.  
  972. NewDoEndPixels:
  973.     mov    esi,ebx
  974.  
  975.     align    4
  976. NDEP_loop:
  977.  
  978. ; compute v coordinate
  979.     mov    eax, ebp    ; get v
  980.     mov    edx, eax
  981.     sar    edx, 31
  982.     idiv    ecx    ; eax = (v/z)
  983.  
  984.     and    eax,3fh    ; mask with height-1
  985.     mov    ebx,eax
  986.  
  987. ; compute u coordinate
  988.     mov    eax,     esi    ; get u
  989.     mov    edx, eax
  990.     sar    edx, 31
  991.     idiv    ecx    ; eax = (u/z)
  992.  
  993.     shl     eax,26
  994.     shld     ebx,eax,6    ; esi = v*64+u
  995.  
  996. ; read 1  pixel
  997.     xor    eax, eax
  998.     mov    al, es:[ebx]    ; get pixel from source bitmap
  999.  
  1000. ; lighting code
  1001.     mov    ebx, _fx_l    ; get temp copy of lighting value
  1002.     mov    ah, bh    ; get lighting level
  1003.     add    ebx, _fx_dl_dx    ; update lighting value
  1004.     mov    _fx_l, ebx    ; save temp copy of lighting value
  1005.  
  1006. ; transparency check
  1007.     cmp    al,255
  1008.     je    NDEP_skip2    ; this pixel is transparent, so don't write it (or light it)
  1009.  
  1010.     mov    al, _gr_fade_table[eax]    ; xlat pixel thru lighting tables
  1011.                     
  1012. ; write 1 pixel
  1013.     mov    [edi],al
  1014. NDEP_skip2:    inc    edi
  1015.     
  1016. ; update deltas
  1017.     add    ebp,_fx_dv_dx
  1018.     add    esi,_fx_du_dx
  1019.     add    ecx,_fx_dz_dx
  1020.     je    _div_0_abort    ; would be dividing by 0, so abort
  1021.  
  1022.     dec    num_left_over
  1023.     jne    NDEP_loop
  1024.  
  1025.     jmp    _none_to_do
  1026.  
  1027. ; ==================================================== No Lighting Code ======================================================
  1028. public tmap_loop_fast_nolight
  1029. tmap_loop_fast_nolight:
  1030.     mov    esi,ebx
  1031.  
  1032.     align    4
  1033. NotDwordAligned1_nolight:
  1034.     test    edi, 11b
  1035.     jz    DwordAligned1_nolight
  1036.  
  1037. ; compute v coordinate
  1038.     mov    eax,ebp    ; get v
  1039.     mov    edx, eax
  1040.     sar    edx, 31
  1041.     idiv    ecx    ; eax = (v/z)
  1042.  
  1043.     and    eax,3fh    ; mask with height-1
  1044.     mov    ebx,eax
  1045.  
  1046. ; compute u coordinate
  1047.     mov    eax, esi    ; get u
  1048.     mov    edx, eax
  1049.     sar    edx, 31
  1050.     idiv    ecx    ; eax = (u/z)
  1051.  
  1052.     shl     eax,26
  1053.     shld     ebx,eax,6    ; esi = v*64+u
  1054.  
  1055. ; read 1  pixel
  1056.     mov    al,es:[ebx]    ; get pixel from source bitmap
  1057.  
  1058. ; write 1 pixel
  1059.     cmp    al,255
  1060.     je    skip6
  1061.     mov    [edi],al
  1062. skip6:    inc    edi
  1063.     
  1064. ; update deltas
  1065.     add    ebp,_fx_dv_dx
  1066.     add    esi,_fx_du_dx
  1067.     add    ecx,_fx_dz_dx
  1068.     je    _div_0_abort    ; would be dividing by 0, so abort
  1069.  
  1070.     dec    _loop_count
  1071.     jns    NotDwordAligned1_nolight
  1072.     jmp    _none_to_do
  1073.  
  1074. DwordAligned1_nolight:
  1075.     mov    ebx,esi
  1076.  
  1077.     mov    eax, _loop_count
  1078.     inc    eax
  1079.     mov    num_left_over, eax
  1080.     shr    eax, NBITS
  1081.  
  1082.     test    eax, -1
  1083.     je    tmap_loop    ; no 2^NBITS chunks, do divide/pixel for whole scanline
  1084.     
  1085.     mov     _loop_count, eax    ; _loop_count = pixels / NPIXS
  1086.     shl    eax, NBITS
  1087.     sub    num_left_over, eax    ; num_left_over = obvious
  1088.         
  1089. ; compute initial v coordinate
  1090.     mov    eax,ebp    ; get v
  1091.     PDIV
  1092.     mov    V0, eax
  1093.  
  1094. ; compute initial u coordinate
  1095.     mov    eax,ebx    ; get u
  1096.     PDIV    
  1097.     mov    U0, eax
  1098.  
  1099. ; Set deltas to NPIXS pixel increments
  1100.     mov    eax, _fx_du_dx
  1101.     shl    eax, NBITS
  1102.     mov    DU1, eax
  1103.     mov    eax, _fx_dv_dx
  1104.     shl    eax, NBITS
  1105.     mov    DV1, eax
  1106.     mov    eax, _fx_dz_dx
  1107.     shl    eax, NBITS
  1108.     mov    DZ1, eax
  1109.  
  1110.     align    4
  1111. TopOfLoop4_nolight:
  1112.     add    ebx, DU1
  1113.     add    ebp, DV1
  1114.     add    ecx, DZ1
  1115.     je    _div_0_abort
  1116.  
  1117. ; Done with ebx, ebp, ecx until next iteration
  1118.     push    ebx
  1119.     push    ecx
  1120.     push    ebp
  1121.     push    edi
  1122.     
  1123. ; Find fixed U1        
  1124.     mov    eax, ebx
  1125.     PDIV
  1126.     mov    ebx, eax    ; ebx = U1 until pop's
  1127.  
  1128. ; Find fixed V1        
  1129.     mov    eax, ebp
  1130.     PDIV
  1131.     mov    ebp, eax    ; ebp = V1 until pop's
  1132.  
  1133.     mov    ecx, U0    ; ecx = U0 until pop's
  1134.     mov    edi, V0    ; edi = V0 until pop's
  1135.  
  1136. ; Make ESI =  V0:U0 in 6:10,6:10 format
  1137.     mov    eax, ecx
  1138.     shr    eax, 6
  1139.     mov    esi, edi
  1140.     shl    esi, 10
  1141.     mov    si, ax
  1142.         
  1143. ; Make EDX = DV:DU in 6:10,6:10 format
  1144.     mov    eax, ebx
  1145.     sub    eax, ecx
  1146.     sar    eax, NBITS+6
  1147.     mov    edx, ebp
  1148.     sub    edx, edi
  1149.     shl    edx, 10-NBITS    ; EDX = V1-V0/ 4 in 6:10 int:frac
  1150.     mov    dx, ax    ; put delta u in low word
  1151.  
  1152. ; Save the U1 and V1 so we don't have to divide on the next iteration
  1153.     mov    U0, ebx
  1154.     mov    V0, ebp
  1155.  
  1156.     pop    edi    ; Restore EDI before using it
  1157.         
  1158.     REPT (1 SHL (NBITS-2))
  1159.     local    skip7, no_trans2, skip1q, skip2q, skip3q, skip4q
  1160.  
  1161. ; Do 1 pixel 
  1162.     mov    eax, esi    ; get u,v
  1163.     shr    eax, 26    ; shift out all but int(v)
  1164.     shld    ax,si,6    ; shift in u, shifting up v
  1165.     add    esi, edx    ; inc u,v
  1166.     mov    cl, es:[eax]    ; load into buffer register
  1167. ;;;    ror    ecx, 8    ; move to next dest pixel
  1168.  
  1169.     mov    eax, esi    ; get u,v
  1170.     shr    eax, 26    ; shift out all but int(v)
  1171.     shld    ax,si,6    ; shift in u, shifting up v
  1172.     mov    ch, es:[eax]    ; load into buffer register
  1173.     add    esi, edx    ; inc u,v
  1174.     ror    ecx, 16    ; move to next dest pixel
  1175.  
  1176.     mov    eax, esi    ; get u,v
  1177.     shr    eax, 26    ; shift out all but int(v)
  1178.     shld    ax,si,6    ; shift in u, shifting up v
  1179.     mov    cl, es:[eax]    ; load into buffer register
  1180.     add    esi, edx    ; inc u,v
  1181. ;;;    ror    ecx, 8    ; move to next dest pixel
  1182.  
  1183.     mov    eax, esi    ; get u,v
  1184.     shr    eax, 26    ; shift out all but int(v)
  1185.     shld    ax,si,6    ; shift in u, shifting up v
  1186.     mov    ch, es:[eax]    ; load into buffer register
  1187.     add    esi, edx    ; inc u,v
  1188.     ror    ecx, 16 ;-- can get rid of this, just write in different order below --     ; move to next dest pixel
  1189.  
  1190.     test    _transparency_on,-1
  1191.     je    no_trans2
  1192.     cmp    ecx,-1
  1193.     je    skip7
  1194.  
  1195.     cmp    cl,255
  1196.     je    skip1q
  1197.     mov    [edi],cl
  1198. skip1q:
  1199.  
  1200.     cmp    ch,255
  1201.     je    skip2q
  1202.     mov    1[edi],ch
  1203. skip2q:
  1204.     ror    ecx,16
  1205.  
  1206.     cmp    cl,255
  1207.     je    skip3q
  1208.     mov    2[edi],cl
  1209. skip3q:
  1210.  
  1211.  
  1212.     cmp    ch,255
  1213.     je    skip4q
  1214.     mov    3[edi],ch
  1215. skip4q:
  1216.  
  1217. ;;    wr_onepix    0
  1218. ;;    wr_onepix    1
  1219. ;;    wr_onepix    2
  1220. ;;    wr_onepix    3
  1221.     jmp    skip7
  1222. no_trans2:
  1223.     mov     [edi],ecx    ; Draw 4 pixels to display
  1224. skip7:    add     edi,4
  1225.  
  1226.     ENDM
  1227.  
  1228.     pop    ebp
  1229.     pop    ecx
  1230.     pop    ebx
  1231.     dec    _loop_count
  1232.     jnz    TopOfLoop4_nolight
  1233.  
  1234. EndOfLoop4_nolight:
  1235.  
  1236.     test    num_left_over, -1
  1237.     je    _none_to_do
  1238.  
  1239. DoEndPixels_nolight:
  1240.     add    ebx, DU1
  1241.     add    ebp, DV1
  1242.     add    ecx, DZ1
  1243.     je    _div_0_abort
  1244.     push    edi    ; use edi as a temporary variable
  1245.  
  1246. ; Find fixed U1        
  1247.     mov    eax, ebx
  1248.     mov    edx,eax
  1249.     shl    eax,ZSHIFT
  1250.     sar    edx,32-ZSHIFT
  1251.     idiv    ecx    ; eax = (v/z)
  1252.     shl    eax, 16-ZSHIFT
  1253.     mov    ebx, eax    ; ebx = U1 until pop's
  1254.  
  1255. ; Find fixed V1        
  1256.     mov    eax, ebp
  1257.     mov    edx,eax
  1258.     shl    eax,ZSHIFT
  1259.     sar    edx,32-ZSHIFT
  1260.     idiv    ecx    ; eax = (v/z)
  1261.     shl    eax, 16-ZSHIFT
  1262.     mov    ebp, eax    ; ebp = V1 until pop's
  1263.  
  1264.     mov    ecx, U0    ; ecx = U0 until pop's
  1265.     mov    edi, V0    ; edi = V0 until pop's
  1266.  
  1267. ; Make ESI =  V0:U0 in 6:10,6:10 format
  1268.     mov    eax, ecx
  1269.     shr    eax, 6
  1270.     mov    esi, edi
  1271.     shl    esi, 10
  1272.     mov    si, ax
  1273.         
  1274. ; Make EDX = DV:DU in 6:10,6:10 format
  1275.     mov    eax, ebx
  1276.     sub    eax, ecx
  1277.     sar    eax, NBITS+6
  1278.     mov    edx, ebp
  1279.     sub    edx, edi
  1280.     shl    edx, 10-NBITS    ; EDX = V1-V0/ 4 in 6:10 int:frac
  1281.     mov    dx, ax    ; put delta u in low word
  1282.  
  1283.     pop    edi    ; Restore EDI before using it
  1284.         
  1285.     mov    ecx, num_left_over
  1286.  
  1287.     ITERATION = 0
  1288.     REPT (1 SHL NBITS)
  1289.     local    skip8
  1290. ; Do 1 pixel 
  1291.     mov    eax, esi    ; get u,v
  1292.     shr    eax, 26    ; shift out all but int(v)
  1293.     shld    ax,si,6    ; shift in u, shifting up v
  1294.     mov    al, es:[eax]    ; load into buffer register
  1295.     add    esi, edx    ; inc u,v
  1296.     cmp    al,255
  1297.     je    skip8
  1298.     mov    [edi+ITERATION], al    ; write pixel
  1299. skip8:    dec    ecx
  1300.     jz    _none_to_do
  1301.     ITERATION = ITERATION + 1
  1302.     ENDM
  1303.  
  1304. ; Should never get here!!!!!
  1305.     int    3
  1306.     jmp    _none_to_do
  1307.  
  1308.     
  1309.  
  1310. _TEXT    ends
  1311.  
  1312.     end
  1313.  
  1314.