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