home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / texmap / tmapdith.asm < prev    next >
Assembly Source File  |  1998-06-08  |  22KB  |  998 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.18 $
  14. ; $Author: mike $
  15. ; $Date: 1994/05/03 11:08:32 $
  16. ;
  17. ; Perspective texture mapper inner loop.
  18. ;
  19. ; $Log: tmap_per.asm $
  20. ; Revision 1.18  1994/05/03  11:08:32  mike
  21. ; Trap divide overflows.
  22. ; Revision 1.17  1994/04/21  15:03:41  mike
  23. ; make faster.
  24. ; Revision 1.16  1994/04/08  16:46:57  john
  25. ; Made 32 fade levels. Hacked.
  26. ; Revision 1.15  1994/03/31  08:35:18  mike
  27. ; Fix quantized-by-4 bug in inner loop.
  28. ; Revision 1.14  1994/03/14  17:41:14  mike
  29. ; Fix bug in unlighted version.
  30. ; Revision 1.13  1994/03/14  15:45:14  mike
  31. ; streamline code.
  32. ; Revision 1.12  1994/01/14  14:01:58  mike
  33. ; *** empty log message ***
  34. ; Revision 1.11  1993/12/18  14:43:44  john
  35. ; Messed around with doing 1/z, the u*(1/z) and v*(1/z)
  36. ; (Went from 23 fps to 21 fps... not good! )
  37. ;
  38. ; Revision 1.10  1993/12/17  16:14:17  john
  39. ; Split lighted/nonlighted, so there is no cmp lighting
  40. ; in the inner loop. 
  41. ; Revision 1.9  1993/12/17  12:34:29  john
  42. ; Made leftover bytes use linear approx instead of correct...
  43. ; should save about 8 divides per scanline on average.
  44. ; Also, took out anti-aliasing code and rearranged to
  45. ; order of some instructions to help on 486 pipelining.
  46. ; (The anti-aliasing code did *not* look good, so I
  47. ; figure there was no reason to keep it in. )
  48. ; Revision 1.8  1993/12/16  18:37:52  mike
  49. ; Align some stuff on 4 byte boundaries.
  50. ; Revision 1.7  1993/11/30  08:44:18  john
  51. ; Made selector set check for < 64*64 bitmaps.
  52. ; Revision 1.6  1993/11/23  17:25:26  john
  53. ; Added safety "and eax, 0fffh" in lighting lookup.
  54. ; Revision 1.5  1993/11/23  15:08:52  mike
  55. ; Fixed lighting bug. 
  56. ; Revision 1.4  1993/11/23  14:38:50  john
  57. ; optimized NORMAL code by switching EBX and ESI, so BH can be used in
  58. ; the lighting process.
  59. ; Revision 1.3  1993/11/23  14:30:53  john
  60. ; Made the perspective tmapper do 1/8 divides; added lighting.
  61. ; Revision 1.2  1993/11/22  10:24:59  mike
  62. ; *** empty log message ***
  63. ; Revision 1.1  1993/09/08  17:29:53  mike
  64. ; Initial revision
  65. ;
  66. ;
  67.  
  68.     .386
  69.  
  70.     public    _fx_u,_fx_v,_fx_z,_fx_du_dx,_fx_dv_dx,_fx_dz_dx,_fx_y,_fx_xleft,_fx_xright
  71.     public    _pixptr
  72.     public    asm_tmap_scanline_per_
  73.  
  74.     include    tmap_inc.asm
  75.  
  76.  public _max_ecx,_min_ecx
  77.  
  78.     extern    _fx_l:dword
  79.     extern     _fx_dl_dx:dword
  80.     extern    _dither_intensity_lighting:dword
  81.     extern    _Lighting_on:dword
  82.     extern    _pixel_data_selector:word, _gr_fade_table_selector:word, _transparency_on:dword
  83.  
  84. _DATA    SEGMENT DWORD PUBLIC USE32 'DATA'
  85.     align    4
  86. ;**_v_window_left    dd    _window_left
  87. ;**_v_window_right    dd    _window_right
  88. ;**_v_window_top    dd    _window_top
  89. ;**_v_window_bottom    dd    _window_bottom
  90.  
  91. ; ---------- These are passed in by the C caller ----------
  92. _fx_u    dd    ?    
  93. _fx_v    dd    ?
  94. _fx_z    dd    ?
  95. _fx_du_dx    dd    ?
  96. _fx_dv_dx    dd    ?
  97. _fx_dz_dx    dd    ?
  98.  
  99. _fx_y    dd    ?
  100. _fx_xleft    dd    ?
  101. _fx_xright    dd    ?
  102.  
  103. _pixptr    dd    ?
  104. ; ----------^^ These are passed in by the C caller ^^----------
  105.  
  106.     public    _x,_loop_count
  107.     align    4
  108. _x    dd    ?
  109. _loop_count    dd    ?
  110.  
  111. _max_ecx    dd    0
  112. _min_ecx    dd    55555555h
  113.  
  114.     public    _per2_flag
  115. _per2_flag    dd    1
  116.  
  117.     public    _scan_doubling_flag, _linear_if_far_flag
  118.  
  119. _scan_doubling_flag    dd 0
  120. _linear_if_far_flag    dd 0
  121.  
  122. ;---------- local variables
  123.     align    4
  124. req_base    dd    ?
  125. req_size    dd    ?
  126. U0    dd    ?
  127. U1    dd    ?
  128. V0    dd    ?
  129. V1    dd    ?
  130. num_left_over    dd    ?
  131. DU1    dd    ?
  132. DV1    dd    ?
  133. DZ1    dd    ?
  134. ;*NO_DITHER _fx_dl_dx1    dd    ?
  135. ;*NO_DITHER _fx_dl_dx2    dd    ?
  136.  
  137. _DATA    ENDS
  138.  
  139. DGROUP    GROUP    _DATA
  140.  
  141.  
  142. _TEXT   SEGMENT DWORD PUBLIC USE32 'CODE'
  143.     ASSUME    DS:_DATA
  144.     ASSUME    CS:_TEXT
  145.  
  146. ; --------------------------------------------------------------------------------------------------
  147. ; Enter:
  148. ;    _xleft    fixed point left x coordinate
  149. ;    _xright    fixed point right x coordinate
  150. ;    _y    fixed point y coordinate
  151. ;    _pixptr    address of source pixel map
  152. ;    _u    fixed point initial u coordinate
  153. ;    _v    fixed point initial v coordinate
  154. ;    _z    fixed point initial z coordinate
  155. ;    _du_dx    fixed point du/dx
  156. ;    _dv_dx    fixed point dv/dx
  157. ;    _dz_dx    fixed point dz/dx
  158.  
  159. ;   for (x = (int) xleft; x <= (int) xright; x++) {
  160. ;      _setcolor(read_pixel_from_tmap(srcb,((int) (u/z)) & 63,((int) (v/z)) & 63));
  161. ;      _setpixel(x,y);
  162. ;
  163. ;      u += du_dx;
  164. ;      v += dv_dx;
  165. ;      z += dz_dx;
  166. ;   }
  167.  
  168.  
  169. asm_tmap_scanline_per_:
  170.     push    es
  171.     push    fs
  172.     pusha
  173.     
  174. ;---------------------------- setup for loop ---------------------------------
  175. ; Setup for loop:    _loop_count  iterations = (int) xright - (int) xleft
  176. ;    esi    source pixel pointer = pixptr
  177. ;    edi    initial row pointer = y*320+x
  178.  
  179. ; set esi = pointer to start of texture map data
  180.     mov    es,_pixel_data_selector    ; selector[0*2]
  181.     mov    fs,_gr_fade_table_selector    ; selector[1*2]    ; fs = bmd_fade_table
  182.  
  183. ; set edi = address of first pixel to modify
  184.     mov    edi,_fx_y
  185.     cmp    edi,_window_bottom
  186.     jae    _none_to_do
  187.  
  188.     imul    edi,_bytes_per_row
  189.     mov    eax,_fx_xleft
  190.     sar    eax,16
  191.     jns    eax_ok
  192.     sub    eax,eax
  193. eax_ok:
  194.     add    edi,eax
  195.     add    edi,write_buffer
  196.  
  197. ; set _loop_count = # of iterations
  198.     mov    eax,_fx_xright
  199.     sar    eax,16
  200.     cmp    eax,_window_right
  201.     jb    eax_ok1
  202.     mov    eax,_window_right
  203. eax_ok1:    cmp    eax,_window_left
  204.     ja    eax_ok2
  205.     mov    eax,_window_left
  206. eax_ok2:
  207.  
  208.     mov    ebx,_fx_xleft
  209.     sar    ebx,16
  210.     sub    eax,ebx
  211.     js    _none_to_do
  212.     cmp    eax,_window_width
  213.     jbe    _ok_to_do
  214.     mov    eax,_window_width
  215. _ok_to_do:
  216.     mov    _loop_count,eax
  217.  
  218. ; lighting values are passed in fixed point, but need to be in 8 bit integer, 8 bit fraction so we can easily
  219. ; get the integer by reading %bh
  220.     sar    _fx_l, 8
  221.     sar    _fx_dl_dx,8
  222.     jns    dl_dx_ok
  223.     inc    _fx_dl_dx    ; round towards 0 for negative deltas
  224. dl_dx_ok:
  225.  
  226. ;*NO_DITHER ;-------------------------- setup for dithering -----------------------------
  227. ;*NO_DITHER ; do dithering, use lighting values which are .5 less than and .5 more than actual value
  228. ;*NO_DITHER     mov    ebx,40h    ; assume dithering on
  229. ;*NO_DITHER     mov    eax,_fx_dl_dx
  230. ;*NO_DITHER     add    eax,ebx    ; add 1/2
  231. ;*NO_DITHER     mov    _fx_dl_dx1,eax
  232. ;*NO_DITHER     mov    eax,_fx_dl_dx
  233. ;*NO_DITHER     sub    eax,ebx
  234. ;*NO_DITHER     mov    _fx_dl_dx2,eax
  235. ;*NO_DITHER     mov    ebx,_fx_xleft
  236. ;*NO_DITHER     shr    ebx,16
  237. ;*NO_DITHER     xor    ebx,_fx_y
  238. ;*NO_DITHER     and    ebx,1
  239. ;*NO_DITHER     jne    dith_1
  240. ;*NO_DITHER     xchg    eax,_fx_dl_dx1
  241. ;*NO_DITHER dith_1:    mov    _fx_dl_dx2,eax
  242.  
  243. ; set initial values
  244.     mov    ebx,_fx_u
  245.     mov    ebp,_fx_v
  246.     mov    ecx,_fx_z
  247.  
  248.     test    _per2_flag,-1
  249.     je    tmap_loop
  250.  
  251.     cmp    _Lighting_on, 0
  252.     je    tmap_loop_fast_nolight
  253.     jmp    tmap_loop_fast
  254.  
  255. ;================ PERSPECTIVE TEXTURE MAP INNER LOOPS ========================
  256. ;
  257. ; Usage in loop:    eax    division, pixel value
  258. ;    ebx    u
  259. ;    ecx    z
  260. ;    edx    division
  261. ;    ebp    v
  262. ;    esi    source pixel pointer
  263. ;    edi    destination pixel pointer
  264.  
  265. ;-------------------- NORMAL PERSPECTIVE TEXTURE MAP LOOP -----------------
  266.     align    4
  267. tmap_loop:
  268.     xchg    ebx, esi
  269.  
  270. ; compute v coordinate
  271.     mov    eax,ebp    ; get v
  272.     cdq
  273.     idiv    ecx    ; eax = (v/z)
  274.  
  275.     and    eax,3fh    ; mask with height-1
  276.     mov    ebx,eax
  277.  
  278. ; compute u coordinate
  279.     mov    eax,esi    ; get u
  280.     cdq
  281.     idiv    ecx    ; eax = (u/z)
  282.  
  283.     shl     eax,26
  284.     shld     ebx,eax,6    ; esi = v*64+u
  285.  
  286. ; read 1  pixel
  287.     movzx    eax,byte ptr es:[ebx]    ; get pixel from source bitmap
  288.  
  289.     cmp    _Lighting_on, 0
  290.     je    NoLight1
  291.  
  292. ; LIGHTING CODE
  293.     mov    ebx, _fx_l    ; get temp copy of lighting value
  294.     mov    ah, bh        ; get lighting level
  295.     add    ebx, _fx_dl_dx    ; update lighting value
  296.  
  297. ;*NO_DITHER     add    ebx, _fx_dl_dx1    ; update lighting value
  298. ;*NO_DITHER    and    eax, (32*256)-1
  299. ;*NO_DITHER     push    eax            ; dithering
  300. ;*NO_DITHER     mov    eax, _fx_dl_dx2
  301. ;*NO_DITHER     xchg    _fx_dl_dx1, eax
  302. ;*NO_DITHER     mov    _fx_dl_dx2, eax
  303. ;*NO_DITHER     pop    eax
  304.  
  305.     mov    al, fs:[eax]    ; xlat pixel thru lighting tables
  306.     mov    _fx_l, ebx    ; save temp copy of lighting value
  307.  
  308. ; transparency check
  309. NoLight1:    cmp    al,255
  310.     je    skip1
  311.  
  312.     mov    [edi],al
  313. skip1:    inc    edi
  314.     
  315. ; update deltas
  316.     add    ebp,_fx_dv_dx
  317.     add    esi,_fx_du_dx
  318.     add    ecx,_fx_dz_dx
  319.     je    _div_0_abort    ; would be dividing by 0, so abort
  320.  
  321.     xchg    esi, ebx
  322.  
  323.     dec    _loop_count
  324.     jns    tmap_loop
  325.  
  326. _none_to_do:    
  327.     popa
  328.     pop    fs
  329.     pop    es
  330.     ret
  331.  
  332. ; We detected a z=0 condition, which seems pretty bogus, don't you think?
  333. ; So, we abort, but maybe we want to know about it.
  334. _div_0_abort:
  335. ;**    int    3
  336.     jmp    _none_to_do
  337.  
  338. ;-------------------------- PER/4 TMAPPER ----------------
  339. ;    x = x1
  340. ;    U0 = u/w; V0 = v/w;
  341. ;    while ( 1 )
  342. ;        u += du_dx*4; v+= dv_dx*4
  343. ;        U1 = u/w; V1 = v/w;
  344. ;        DUDX = (U1-U0)/4; DVDX = (V1-V0)/4;
  345. ;
  346. ;    ; Pixel 0
  347. ;        pixels = texmap[V0*64+U0];
  348. ;        U0 += DUDX; V0 += DVDX
  349. ;    ; Pixel 1
  350. ;        pixels = (pixels<<8)+texmap[V0*64+U0];
  351. ;        U0 += DUDX; V0 += DVDX
  352. ;    ; Pixel 2
  353. ;        pixels = (pixels<<8)+texmap[V0*64+U0];
  354. ;        U0 += DUDX; V0 += DVDX
  355. ;    ; Pixel 3
  356. ;        pixels = (pixels<<8)+texmap[V0*64+U0];
  357. ;
  358. ;        screen[x] = pixel
  359. ;        x += 4;
  360. ;        U0 = U1; V0 = V1 
  361.  
  362. NBITS = 3
  363. ZSHIFT = 3
  364.  
  365.  
  366. PDIV MACRO
  367. ; Returns EAX/ECX in 16.16 format in EAX. Trashes EDX
  368. ;          sig bits   6.3
  369. ;--old--    cdq
  370. ;--old--    shld    edx,eax, ZSHIFT
  371. ;--old--    lea    eax, [eax*8]
  372. ;--old--    idiv    ecx    ; eax = (v/z)
  373. ;--old--    shl    eax, 16-ZSHIFT
  374.  
  375.     mov    edx,eax
  376.     shl    eax,ZSHIFT
  377.     sar    edx,32-ZSHIFT
  378.     idiv    ecx    ; eax = (v/z)
  379.     shl    eax, 16-ZSHIFT
  380.  
  381. ENDM
  382.  
  383. wr_onepix    macro    num
  384.     local    skip
  385.     cmp    cl,255
  386.     je    skip
  387.     mov    num[edi],cl
  388.     ror    ecx,8
  389. skip:
  390.     endm
  391.  
  392. public tmap_loop_fast
  393.  
  394. ; -------------------------------------- Start of Getting Dword Aligned ----------------------------------------------
  395. ;    ebx    fx_u
  396.  
  397. tmap_loop_fast:
  398.     mov    esi,ebx
  399.  
  400.     align    4
  401. NotDwordAligned1:
  402.     test    edi, 11b
  403.     jz    DwordAligned1
  404.  
  405. ; compute v coordinate
  406.     mov    eax,ebp    ; get v
  407.     cdq
  408.     idiv    ecx    ; eax = (v/z)
  409.  
  410.     and    eax,3fh    ; mask with height-1
  411.     mov    ebx,eax
  412.  
  413. ; compute u coordinate
  414.     mov    eax,esi    ; get u
  415.     cdq
  416.     idiv    ecx    ; eax = (u/z)
  417.  
  418.     shl     eax,26
  419.     shld     ebx,eax,6    ; esi = v*64+u
  420.  
  421. ; read 1  pixel
  422.     movzx    eax,byte ptr es:[ebx]    ; get pixel from source bitmap
  423.  
  424. ; lighting code
  425.     mov    ebx, _fx_l    ; get temp copy of lighting value
  426.     mov    ah, bh    ; get lighting level
  427.     add    ebx, _fx_dl_dx    ; update lighting value
  428.     mov    _fx_l, ebx    ; save temp copy of lighting value
  429.  
  430. ; transparency check
  431.     cmp    al,255
  432.     je    skip2    ; this pixel is transparent, so don't write it (or light it)
  433.  
  434.     mov    al, fs:[eax]    ; xlat pixel thru lighting tables
  435.                     
  436. ; write 1 pixel
  437.     mov    [edi],al
  438. skip2:    inc    edi
  439.     
  440. ; update deltas
  441.     add    ebp,_fx_dv_dx
  442.     add    esi,_fx_du_dx
  443.     add    ecx,_fx_dz_dx
  444.     je    _div_0_abort    ; would be dividing by 0, so abort
  445.  
  446.     dec    _loop_count
  447.     jns    NotDwordAligned1
  448.     jmp    _none_to_do
  449.  
  450. ; -------------------------------------- End of Getting Dword Aligned ----------------------------------------------
  451.  
  452. DwordAligned1:
  453.     mov    ebx,esi    ; get fx_u
  454.  
  455.     mov    eax, _loop_count
  456.     inc    eax
  457.     mov    num_left_over, eax
  458.     shr    eax, NBITS
  459.  
  460.     cmp    eax, 0        
  461.     je    tmap_loop
  462.     
  463.     mov     _loop_count, eax    ; _loop_count = pixels / NPIXS
  464.     shl    eax, 3
  465.     sub    num_left_over, eax    ; num_left_over = obvious
  466.         
  467. ; compute initial v coordinate
  468.     mov    eax,ebp    ; get v
  469.     mov    edx,ebp
  470.     shl    eax,ZSHIFT
  471.     sar    edx,32-ZSHIFT
  472.     idiv    ecx    ; eax = (v/z)
  473.     shl    eax, 16-ZSHIFT
  474.     mov    V0, eax
  475.  
  476. ; compute initial u coordinate
  477.     mov    eax,ebx    ; get u
  478.     mov    edx,ebx
  479.     shl    eax,ZSHIFT
  480.     sar    edx,32-ZSHIFT
  481.     idiv    ecx    ; eax = (v/z)
  482.     shl    eax, 16-ZSHIFT
  483.     mov    U0, eax
  484.  
  485. ; Set deltas to NPIXS pixel increments
  486.     mov    eax, _fx_du_dx
  487.     shl    eax, 3
  488.     mov    DU1, eax
  489.     mov    eax, _fx_dv_dx
  490.     shl    eax, 3
  491.     mov    DV1, eax
  492.     mov    eax, _fx_dz_dx
  493.     shl    eax, 3
  494.     mov    DZ1, eax
  495.  
  496.     align    4
  497. TopOfLoop4:
  498.     add    ebx, DU1
  499.     add    ebp, DV1
  500.     add    ecx, DZ1
  501.     je    _div_0_abort    ; would be dividing by 0, so abort
  502.  
  503. ; Done with ebx, ebp, ecx until next iteration
  504.     push    ebx
  505.     push    ecx
  506.     push    ebp
  507.     push    edi
  508.     
  509. ; Find fixed U1        
  510.     mov    eax, ebx
  511.     mov    edx,ebx
  512.     shl    eax,ZSHIFT
  513.     sar    edx,32-ZSHIFT
  514.     idiv    ecx    ; eax = (v/z)
  515.     shl    eax, 16-ZSHIFT
  516.     mov    ebx, eax    ; ebx = U1 until pop's
  517.  
  518. ; Find fixed V1        
  519.     mov    eax, ebp
  520.     mov    edx, ebp
  521.     shl    eax,ZSHIFT
  522.     sar    edx,32-ZSHIFT
  523.     idiv    ecx    ; eax = (v/z)
  524.  
  525.     mov    ecx, U0    ; ecx = U0 until pop's
  526.     mov    edi, V0    ; edi = V0 until pop's
  527.  
  528.     shl    eax, 16-ZSHIFT
  529.     mov    ebp, eax    ; ebp = V1 until pop's
  530.  
  531. ; Make ESI =  V0:U0 in 6:10,6:10 format
  532.     mov    eax, ecx
  533.     shr    eax, 6
  534.     mov    esi, edi
  535.     shl    esi, 10
  536.     mov    si, ax
  537.         
  538. ; Make EDX = DV:DU in 6:10,6:10 format
  539.     mov    eax, ebx
  540.     sub    eax, ecx
  541.     sar    eax, NBITS+6
  542.     mov    edx, ebp
  543.     sub    edx, edi
  544.     shl    edx, 10-NBITS    ; EDX = V1-V0/ 4 in 6:10 int:frac
  545.     mov    dx, ax    ; put delta u in low word
  546.  
  547. ; Save the U1 and V1 so we don't have to divide on the next iteration
  548.     mov    U0, ebx
  549.     mov    V0, ebp
  550.  
  551.     pop    edi    ; Restore EDI before using it
  552.         
  553. ; LIGHTING CODE
  554.     mov    ebx, _fx_l
  555.     mov    ebp, _fx_dl_dx
  556.  
  557.     test    _transparency_on,-1
  558.     je    no_trans1
  559.  
  560.     REPT (1 SHL (NBITS-2))
  561.     local    skip3,no_trans1
  562.         REPT 2
  563.     local    skipa1,skipa2
  564.  
  565.     mov    eax, esi    ; get u,v
  566.     shr    eax, 26    ; shift out all but int(v)
  567.     shld    ax,si,6    ; shift in u, shifting up v
  568.     add    esi, edx    ; inc u,v
  569.     mov     al, es:[eax]    ; get pixel from source bitmap
  570.     cmp    al,255
  571.     je    skipa1
  572.     mov    ah, bh    ; form lighting table lookup value
  573.     add    ebx, ebp    ; update lighting value
  574.     mov    al, fs:[eax]    ; xlat thru lighting table into dest buffer
  575.     mov    [edi],al
  576. skipa1:
  577.     inc    edi
  578.  
  579. ; Do odd pixel
  580.     mov    eax, esi    ; get u,v
  581.     shr    eax, 26    ; shift out all but int(v)
  582.     shld    ax,si,6    ; shift in u, shifting up v
  583.     add    esi, edx    ; inc u,v
  584.     mov     al, es:[eax]    ; get pixel from source bitmap
  585.     cmp    al,255
  586.     je    skipa2
  587.     mov    ah, bh    ; form lighting table lookup value
  588.     add    ebx, ebp    ; update lighting value
  589.     mov    al, fs:[eax]    ; xlat thru lighting table into dest buffer
  590.     mov    [edi],al
  591. skipa2:
  592.     inc    edi
  593.  
  594.         ENDM
  595.  
  596.     ENDM
  597.     jmp    cont1
  598.  
  599. ; -------------------------------------------------------
  600. no_trans1:
  601.     REPT (1 SHL (NBITS-2))
  602.     local    skip3
  603.         REPT 2
  604.  
  605.     mov    eax, esi    ; get u,v
  606.     shr    eax, 26    ; shift out all but int(v)
  607.     shld    ax,si,6    ; shift in u, shifting up v
  608.     add    esi, edx    ; inc u,v
  609.     mov     al, es:[eax]    ; get pixel from source bitmap
  610.     mov    ah, bh    ; form lighting table lookup value
  611.     add    ebx, ebp    ; update lighting value
  612.     mov    cl, fs:[eax]    ; xlat thru lighting table into dest buffer
  613.  
  614. ; Do odd pixel
  615.     mov    eax, esi    ; get u,v
  616.     shr    eax, 26    ; shift out all but int(v)
  617.     shld    ax,si,6    ; shift in u, shifting up v
  618.     add    esi, edx    ; inc u,v
  619.     mov     al, es:[eax]    ; get pixel from source bitmap
  620.     mov    ah, bh    ; form lighting table lookup value
  621.     add    ebx, ebp    ; update lighting value
  622.     mov    ch, fs:[eax]    ; xlat thru lighting table into dest buffer
  623.  
  624.     ror    ecx, 16    ; move to next double dest pixel position
  625.  
  626.         ENDM
  627.     mov     [edi],ecx    ; Draw 4 pixels to display
  628. skip3:    add     edi,4
  629.  
  630.     ENDM
  631.  
  632. cont1:
  633.  
  634. ; -------------------------------------------------------
  635.  
  636. ; LIGHTING CODE
  637.     mov    _fx_l, ebx
  638.     pop    ebp
  639.     pop    ecx
  640.     pop    ebx
  641.     dec    _loop_count
  642.     jnz    TopOfLoop4
  643.  
  644. EndOfLoop4:
  645.     cmp    num_left_over, 0
  646.     je    _none_to_do
  647.  
  648. ; ----------------------------------------- Start of LeftOver Pixels ------------------------------------------
  649. DoEndPixels:
  650.     add    ebx, DU1
  651.     add    ebp, DV1
  652.     add    ecx, DZ1
  653.     je    _div_0_abort
  654.  
  655.     push    edi    ; use edi as a temporary variable
  656.  
  657.     cmp    ecx,10
  658.     jg    ecx_ok
  659.     mov    ecx,10
  660. ecx_ok:
  661.  
  662. ; Find fixed U1        
  663.     mov    eax, ebx
  664.     PDIV
  665.     mov    ebx, eax    ; ebx = U1 until pop's
  666.  
  667. ; Find fixed V1        
  668.     mov    eax, ebp
  669.     PDIV
  670.     mov    ebp, eax    ; ebp = V1 until pop's
  671.  
  672.     mov    ecx, U0    ; ecx = U0 until pop's
  673.     mov    edi, V0    ; edi = V0 until pop's
  674.  
  675. ; Make ESI =  V0:U0 in 6:10,6:10 format
  676.     mov    eax, ecx
  677.     shr    eax, 6
  678.     mov    esi, edi
  679.     shl    esi, 10
  680.     mov    si, ax
  681.         
  682. ; Make EDX = DV:DU in 6:10,6:10 format
  683.     mov    eax, ebx
  684.     sub    eax, ecx
  685.     sar    eax, NBITS+6
  686.     mov    edx, ebp
  687.     sub    edx, edi
  688.     shl    edx, 10-NBITS    ; EDX = V1-V0/ 4 in 6:10 int:frac
  689.     mov    dx, ax    ; put delta u in low word
  690.  
  691.     pop    edi    ; Restore EDI before using it
  692.         
  693.     mov    ecx, num_left_over
  694.  
  695. ; LIGHTING CODE
  696.     mov    ebx, _fx_l
  697.     mov    ebp, _fx_dl_dx
  698.  
  699.     ITERATION = 0
  700.     REPT (1 SHL (NBITS-1))
  701.     local    skip4, skip5
  702. ; Do even pixel
  703.     mov    eax, esi    ; get u,v
  704.     shr    eax, 26    ; shift out all but int(v)
  705.     shld    ax,si,6    ; shift in u, shifting up v
  706.     mov     al, es:[eax]    ; get pixel from source bitmap
  707.     add    esi, edx    ; inc u,v
  708.     mov    ah, bh    ; form lighting table lookup value
  709.     ;SAFETYand    ah,0fh
  710.     add    ebx, ebp    ; update lighting value
  711.     cmp    al,255
  712.     je    skip4
  713.     mov    al, fs:[eax]    ; xlat thru lighting table into dest buffer
  714.     mov    [edi+ITERATION], al    ; write pixel
  715. skip4:    dec    ecx
  716.     jz    _none_to_do
  717.     ITERATION = ITERATION + 1
  718.  
  719. ; Do odd pixel
  720.     mov    eax, esi    ; get u,v
  721.     shr    eax, 26    ; shift out all but int(v)
  722.     shld    ax,si,6    ; shift in u, shifting up v
  723.     mov     al, es:[eax]    ; get pixel from source bitmap
  724.     add    esi, edx    ; inc u,v
  725.     mov    ah, bh    ; form lighting table lookup value
  726.     add    ebx, _fx_dl_dx    ; update lighting value
  727.     cmp    al,255
  728.     je    skip5
  729.     ;SAFETYand    ah,0fh
  730.     mov    al, fs:[eax]    ; xlat thru lighting table into dest buffer
  731.     mov    [edi+ITERATION], al    ; write pixel
  732. skip5:    dec    ecx
  733.     jz    _none_to_do
  734.     ITERATION = ITERATION + 1
  735.     ENDM
  736.  
  737. ; ----------------------------------------- End of LeftOver Pixels ------------------------------------------
  738.  
  739. ; Should never get here!!!!
  740.     int    3
  741.     jmp    _none_to_do
  742.  
  743. ; ==================================================== No Lighting Code ======================================================
  744. public tmap_loop_fast_nolight
  745. tmap_loop_fast_nolight:
  746.     mov    esi,ebx
  747.  
  748.     align    4
  749. NotDwordAligned1_nolight:
  750.     test    edi, 11b
  751.     jz    DwordAligned1_nolight
  752.  
  753. ; compute v coordinate
  754.     mov    eax,ebp    ; get v
  755.     cdq
  756.     idiv    ecx    ; eax = (v/z)
  757.  
  758.     and    eax,3fh    ; mask with height-1
  759.     mov    ebx,eax
  760.  
  761. ; compute u coordinate
  762.     mov    eax,esi    ; get u
  763.     cdq
  764.     idiv    ecx    ; eax = (u/z)
  765.  
  766.     shl     eax,26
  767.     shld     ebx,eax,6    ; esi = v*64+u
  768.  
  769. ; read 1  pixel
  770.     mov    al,es:[ebx]    ; get pixel from source bitmap
  771.  
  772. ; write 1 pixel
  773.     cmp    al,255
  774.     je    skip6
  775.     mov    [edi],al
  776. skip6:    inc    edi
  777.     
  778. ; update deltas
  779.     add    ebp,_fx_dv_dx
  780.     add    esi,_fx_du_dx
  781.     add    ecx,_fx_dz_dx
  782.     je    _div_0_abort    ; would be dividing by 0, so abort
  783.  
  784.     dec    _loop_count
  785.     jns    NotDwordAligned1_nolight
  786.     jmp    _none_to_do
  787.  
  788. DwordAligned1_nolight:
  789.     mov    ebx,esi
  790.  
  791.     mov    eax, _loop_count
  792.     inc    eax
  793.     mov    num_left_over, eax
  794.     shr    eax, NBITS
  795.  
  796.     cmp    eax, 0        
  797.     je    tmap_loop
  798.     
  799.     mov     _loop_count, eax    ; _loop_count = pixels / NPIXS
  800.     shl    eax, NBITS
  801.     sub    num_left_over, eax    ; num_left_over = obvious
  802.         
  803. ; compute initial v coordinate
  804.     mov    eax,ebp    ; get v
  805.     PDIV
  806.     mov    V0, eax
  807.  
  808. ; compute initial u coordinate
  809.     mov    eax,ebx    ; get u
  810.     PDIV    
  811.     mov    U0, eax
  812.  
  813. ; Set deltas to NPIXS pixel increments
  814.     mov    eax, _fx_du_dx
  815.     shl    eax, NBITS
  816.     mov    DU1, eax
  817.     mov    eax, _fx_dv_dx
  818.     shl    eax, NBITS
  819.     mov    DV1, eax
  820.     mov    eax, _fx_dz_dx
  821.     shl    eax, NBITS
  822.     mov    DZ1, eax
  823.  
  824.     align    4
  825. TopOfLoop4_nolight:
  826.     add    ebx, DU1
  827.     add    ebp, DV1
  828.     add    ecx, DZ1
  829.     je    _div_0_abort
  830.  
  831. ; Done with ebx, ebp, ecx until next iteration
  832.     push    ebx
  833.     push    ecx
  834.     push    ebp
  835.     push    edi
  836.     
  837. ; Find fixed U1        
  838.     mov    eax, ebx
  839.     PDIV
  840.     mov    ebx, eax    ; ebx = U1 until pop's
  841.  
  842. ; Find fixed V1        
  843.     mov    eax, ebp
  844.     PDIV
  845.     mov    ebp, eax    ; ebp = V1 until pop's
  846.  
  847.     mov    ecx, U0    ; ecx = U0 until pop's
  848.     mov    edi, V0    ; edi = V0 until pop's
  849.  
  850. ; Make ESI =  V0:U0 in 6:10,6:10 format
  851.     mov    eax, ecx
  852.     shr    eax, 6
  853.     mov    esi, edi
  854.     shl    esi, 10
  855.     mov    si, ax
  856.         
  857. ; Make EDX = DV:DU in 6:10,6:10 format
  858.     mov    eax, ebx
  859.     sub    eax, ecx
  860.     sar    eax, NBITS+6
  861.     mov    edx, ebp
  862.     sub    edx, edi
  863.     shl    edx, 10-NBITS    ; EDX = V1-V0/ 4 in 6:10 int:frac
  864.     mov    dx, ax    ; put delta u in low word
  865.  
  866. ; Save the U1 and V1 so we don't have to divide on the next iteration
  867.     mov    U0, ebx
  868.     mov    V0, ebp
  869.  
  870.     pop    edi    ; Restore EDI before using it
  871.         
  872.     REPT (1 SHL (NBITS-2))
  873.     local    skip7, no_trans2
  874.         REPT 4    
  875. ; Do 1 pixel 
  876.     mov    eax, esi    ; get u,v
  877.     shr    eax, 26    ; shift out all but int(v)
  878.     shld    ax,si,6    ; shift in u, shifting up v
  879.     mov    cl, es:[eax]    ; load into buffer register
  880.     add    esi, edx    ; inc u,v
  881.     ror    ecx, 8    ; move to next dest pixel
  882.  
  883.         ENDM
  884.         
  885.     test    _transparency_on,-1
  886.     je    no_trans2
  887.     cmp    ecx,-1
  888.     je    skip7
  889.  
  890.     wr_onepix    0
  891.     wr_onepix    1
  892.     wr_onepix    2
  893.     wr_onepix    3
  894.     jmp    skip7
  895. no_trans2:
  896.     mov     [edi],ecx    ; Draw 4 pixels to display
  897. skip7:    add     edi,4
  898.  
  899.     ENDM
  900.  
  901.     pop    ebp
  902.     pop    ecx
  903.     pop    ebx
  904.     dec    _loop_count
  905.     jnz    TopOfLoop4_nolight
  906.  
  907. EndOfLoop4_nolight:
  908.  
  909.     cmp    num_left_over, 0
  910.     je    _none_to_do
  911.  
  912. DoEndPixels_nolight:
  913.     add    ebx, DU1
  914.     add    ebp, DV1
  915.     add    ecx, DZ1
  916.     je    _div_0_abort
  917.     push    edi    ; use edi as a temporary variable
  918.  
  919. ; Find fixed U1        
  920.     mov    eax, ebx
  921.     PDIV
  922.     mov    ebx, eax    ; ebx = U1 until pop's
  923.  
  924. ; Find fixed V1        
  925.     mov    eax, ebp
  926.     PDIV
  927.     mov    ebp, eax    ; ebp = V1 until pop's
  928.  
  929.     mov    ecx, U0    ; ecx = U0 until pop's
  930.     mov    edi, V0    ; edi = V0 until pop's
  931.  
  932. ; Make ESI =  V0:U0 in 6:10,6:10 format
  933.     mov    eax, ecx
  934.     shr    eax, 6
  935.     mov    esi, edi
  936.     shl    esi, 10
  937.     mov    si, ax
  938.         
  939. ; Make EDX = DV:DU in 6:10,6:10 format
  940.     mov    eax, ebx
  941.     sub    eax, ecx
  942.     sar    eax, NBITS+6
  943.     mov    edx, ebp
  944.     sub    edx, edi
  945.     shl    edx, 10-NBITS    ; EDX = V1-V0/ 4 in 6:10 int:frac
  946.     mov    dx, ax    ; put delta u in low word
  947.  
  948.     pop    edi    ; Restore EDI before using it
  949.         
  950.     mov    ecx, num_left_over
  951.  
  952.     ITERATION = 0
  953.     REPT (1 SHL NBITS)
  954.     local    skip8
  955. ; Do 1 pixel 
  956.     mov    eax, esi    ; get u,v
  957.     shr    eax, 26    ; shift out all but int(v)
  958.     shld    ax,si,6    ; shift in u, shifting up v
  959.     mov    al, es:[eax]    ; load into buffer register
  960.     add    esi, edx    ; inc u,v
  961.     cmp    al,255
  962.     je    skip8
  963.     mov    [edi+ITERATION], al    ; write pixel
  964. skip8:    dec    ecx
  965.     jz    _none_to_do
  966.     ITERATION = ITERATION + 1
  967.     ENDM
  968.  
  969. ; Should never get here!!!!!
  970.     int    3
  971.     jmp    _none_to_do
  972.  
  973.     
  974.  
  975. _TEXT    ends
  976.  
  977.     end
  978.  
  979. 
  980.