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