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