home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / texmap / tmap_ll.asm < prev    next >
Assembly Source File  |  1998-06-08  |  12KB  |  487 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_ll.asm $
  13. ; $Revision: 1.10 $
  14. ; $Author: john $
  15. ; $Date: 1995/02/20 18:22:54 $
  16. ;
  17. ; Linear, lighted texture mapper inner loop.
  18. ;
  19. ; $Log: tmap_ll.asm $
  20. ; Revision 1.10  1995/02/20  18:22:54  john
  21. ; Put all the externs in the assembly modules into tmap_inc.asm.
  22. ; Also, moved all the C versions of the inner loops into a new module, 
  23. ; scanline.c.
  24. ; Revision 1.9  1995/02/20  17:09:06  john
  25. ; Added code so that you can build the tmapper with no assembly!
  26. ; Revision 1.8  1994/11/19  23:52:56  mike
  27. ; rip out big unrolled loop to save 25K....remember when we cared more about speed?
  28. ; Revision 1.7  1994/11/12  16:39:41  mike
  29. ; jae to ja.
  30. ; Revision 1.6  1994/03/14  15:45:08  mike
  31. ; streamline code.
  32. ; Revision 1.5  1994/01/24  13:13:12  mike
  33. ; dithering.
  34. ; Revision 1.4  1994/01/14  14:02:47  mike
  35. ; *** empty log message ***
  36. ; Revision 1.3  1993/12/17  20:00:16  mike
  37. ; Change default setting of dither_intensity_lighting from 1 to 0
  38. ; Revision 1.2  1993/11/22  10:24:50  mike
  39. ; *** empty log message ***
  40. ; Revision 1.1  1993/09/08  17:29:52  mike
  41. ; Initial revision
  42. ;
  43. ;
  44.  
  45.     .386
  46.  
  47.     public    asm_tmap_scanline_lin_lighted_
  48.  
  49.     include    tmap_inc.asm
  50.  
  51. _DATA    SEGMENT DWORD PUBLIC USE32 'DATA'
  52.  
  53. ALLOW_DITHERING    equ    1
  54.  
  55. _fx_dl_dx1    dd    ?
  56. _fx_dl_dx2    dd    ?
  57.  
  58. _loop_count    dd    ?
  59.  
  60. _DATA    ENDS
  61.  
  62. DGROUP    GROUP    _DATA
  63.  
  64. _TEXT   SEGMENT DWORD PUBLIC USE32 'CODE'
  65.  
  66.     ASSUME    DS:_DATA
  67.     ASSUME    CS:_TEXT
  68.  
  69. ; --------------------------------------------------------------------------------------------------
  70. ; Enter:
  71. ;    _xleft    fixed point left x coordinate
  72. ;    _xright    fixed point right x coordinate
  73. ;    _y    fixed point y coordinate
  74. ;    _pixptr    address of source pixel map
  75. ;    _u    fixed point initial u coordinate
  76. ;    _v    fixed point initial v coordinate
  77. ;    _du_dx    fixed point du/dx
  78. ;    _dv_dx    fixed point dv/dx
  79.  
  80. ;   for (x = (int) xleft; x <= (int) xright; x++) {
  81. ;      _setcolor(read_pixel_from_tmap(srcb,((int) (u/z)) & 63,((int) (v/z)) & 63));
  82. ;      _setpixel(x,y);
  83. ;
  84. ;      u += du_dx;
  85. ;      v += dv_dx;
  86. ;      z += dz_dx;
  87. ;   }
  88.  
  89.     align    4
  90. asm_tmap_scanline_lin_lighted_:
  91.     push    es
  92.     push    fs
  93.     pusha
  94.  
  95.     mov    es,_pixel_data_selector    ; selector[0*2]
  96.     mov    fs,_gr_fade_table_selector    ; selector[1*2]    ; fs = bmd_fade_table
  97.  
  98. ; Setup for loop:    _loop_count  iterations = (int) xright - (int) xleft
  99. ;   esi    source pixel pointer = pixptr
  100. ;   edi    initial row pointer = y*320+x
  101.  
  102. ; set esi = pointer to start of texture map data
  103.     mov    esi,_pixptr
  104.  
  105. ; set edi = address of first pixel to modify
  106.     mov    edi,_fx_y    ; this is actually an int
  107.     cmp    edi,_window_bottom
  108.     ja    all_done
  109.  
  110.     imul    edi,_bytes_per_row
  111.     mov    ebx,_fx_xleft
  112.     test    ebx,ebx
  113.     jns    ebx_ok
  114.     sub    ebx,ebx
  115. ebx_ok:
  116.     add    edi,ebx
  117.     add    edi,write_buffer
  118.  
  119. ; set _loop_count = # of iterations
  120.     mov    eax,_fx_xright
  121.     cmp    eax,_window_right
  122.     jl    eax_ok1
  123.     mov    eax,_window_right
  124. eax_ok1:    cmp    eax,_window_left
  125.     jg    eax_ok2
  126.     mov    eax,_window_left
  127. eax_ok2:
  128.  
  129.     sub    eax,ebx
  130.     js    all_done
  131.     cmp    eax,_window_width
  132.     jbe    _ok_to_do
  133.     mov    eax,_window_width
  134. _ok_to_do:
  135.     mov    _loop_count,eax
  136.  
  137. ;    edi    destination pixel pointer
  138.  
  139.  
  140.     mov    ecx,offset _lighting_tables
  141.     mov    eax,_fx_u    ; get 32 bit u coordinate
  142.     shr    eax,6    ; get 6:10 int:frac u coordinate into low word
  143.     mov    ebp,_fx_v    ; get 32 bit v coordinate
  144.     shl    ebp,10    ; put 6:10 int:frac into high word
  145.     mov    bp,ax    ; put u coordinate in low word
  146.  
  147.     mov    eax,_fx_du_dx    ; get 32 bit delta u
  148.     shr    eax,6    ; get 6:10 int:frac delta u into low word
  149.     mov    edx,_fx_dv_dx    ; get 32 bit delta v
  150.     shl    edx,10    ; put 6:10 int:frac into high word
  151.     mov    dx,ax    ; put delta u in low word
  152.  
  153.     sar    dword ptr _fx_dl_dx,8
  154.     jns    dl_dx_ok
  155.     inc    _fx_dl_dx    ; round towards 0 for negative deltas
  156. dl_dx_ok:
  157.  
  158.   if ALLOW_DITHERING
  159. ; do dithering, use lighting values which are .5 less than and .5 more than actual value
  160.     mov    ebx,80h    ; assume dithering on
  161.     test    _dither_intensity_lighting,-1
  162.     jne    do_dither
  163.     sub    ebx,ebx    ; no dithering
  164. do_dither:
  165.     mov    eax,_fx_dl_dx
  166.     add    eax,ebx    ; add 1/2
  167.     mov    _fx_dl_dx1,eax
  168.     sub    eax,ebx
  169.     sub    eax,ebx
  170.     mov    _fx_dl_dx2,eax
  171.     mov    ebx,_fx_xleft
  172.     xor    ebx,_fx_y
  173.     and    ebx,1
  174.     jne    dith_1
  175.     xchg    eax,_fx_dl_dx1
  176. dith_1:    mov    _fx_dl_dx2,eax
  177.   endif
  178.  
  179.     mov    ebx,_fx_l
  180.  
  181. ; lighting values are passed in fixed point, but need to be in 8 bit integer, 8 bit fraction so we can easily
  182. ; get the integer by reading %bh
  183.     sar    ebx,8
  184.  
  185.     test    _transparency_on,-1
  186.     jne    do_transparency_ll
  187.  
  188. ;; esi, ecx should be free
  189. loop_test = 1    ; set to 1 to run as loop for better profiling
  190.  if loop_test
  191.     mov    esi,_fx_dl_dx
  192.  
  193.     mov    ecx,_loop_count
  194.     inc    ecx
  195.     shr    ecx,1
  196.     je    one_more_pix
  197.     pushf
  198.  
  199.     align    4
  200.  
  201. loop1:
  202.     mov    eax,ebp    ; get u, v
  203.     shr    eax,26    ; shift out all but int(v)
  204.     shld    ax,bp,6    ; shift in u, shifting up v
  205.  
  206.     add    ebp,edx    ; u += du, v += dv
  207.  
  208.     mov    al,es:[eax]    ; get pixel from source bitmap
  209.     mov    ah,bh    ; get lighting table
  210.     add    ebx,esi    ; _fx_dl_dx    ; update lighting value
  211.     mov    al,fs:[eax]    ; xlat pixel through lighting tables
  212.     mov    [edi],al    ; write pixel...
  213.     inc    edi    ; ...and advance
  214.  
  215. ; --- ---
  216.  
  217.     mov    eax,ebp    ; get u, v
  218.     shr    eax,26    ; shift out all but int(v)
  219.     shld    ax,bp,6    ; shift in u, shifting up v
  220.  
  221.     add    ebp,edx    ; u += du, v += dv
  222.  
  223.     mov    al,es:[eax]    ; get pixel from source bitmap
  224.     mov    ah,bh    ; get lighting table
  225.     add    ebx,esi    ; _fx_dl_dx    ; update lighting value
  226.     mov    al,fs:[eax]    ; xlat pixel through lighting tables
  227.     mov    [edi],al    ; write pixel...
  228.     inc    edi    ; ...and advance
  229.  
  230.     dec    ecx    ; _loop_count
  231.     jne    loop1
  232.  
  233.     popf
  234.     jnc    all_done
  235.  
  236. one_more_pix:    mov    eax,ebp    ; get u, v
  237.     shr    eax,26    ; shift out all but int(v)
  238.     shld    ax,bp,6    ; shift in u, shifting up v
  239.  
  240.     mov    al,es:[eax]    ; get pixel from source bitmap
  241.     mov    ah,bh    ; get lighting table
  242.     mov    al,fs:[eax]    ; xlat pixel through lighting tables
  243.     mov    [edi],al    ; write pixel...
  244.  
  245. all_done:    popa
  246.     pop    fs
  247.     pop    es
  248.     ret
  249.  
  250.  
  251.   else
  252.  
  253. ; usage:
  254. ;    eax    work
  255. ;    ebx    lighting value
  256. ;    ecx    _lighting_tables
  257. ;    edx    du, dv 6:10:6:10
  258. ;    ebp    u, v coordinates 6:10:6:10
  259. ;    esi    pointer to source bitmap
  260. ;    edi    write address
  261.  
  262. _size = (_end1 - _start1)/num_iters
  263. ;  note: if eax is odd, you will not be writing the last pixel, you must clean up at the end
  264.   if ALLOW_DITHERING
  265.     mov eax,_loop_count
  266.     shr eax,1
  267.     neg eax
  268.     add eax,num_iters
  269.   else
  270.     mov    eax,num_iters
  271.     sub    eax,_loop_count
  272.  
  273.   endif
  274.     imul    eax,eax,dword ptr _size
  275.     add    eax,offset _start1
  276.     jmp    eax
  277.  
  278.     align    4
  279. _start1:
  280.  
  281. ; usage:
  282. ;    eax    work
  283. ;    ebx    lighting value
  284. ;    ecx    _lighting_tables
  285. ;    edx    du, dv 6:10:6:10
  286. ;    ebp    u, v coordinates 6:10:6:10
  287. ;    esi    pointer to source bitmap
  288. ;    edi    write address
  289.  
  290. ; do all but the last pixel in the unwound loop, last pixel done separately because less work is needed
  291.   rept num_iters
  292.  if 1
  293.  
  294. ;**; inner loop if lighting value is constant
  295. ;**; can be optimized if source bitmap pixels are stored as words, then the mov ah,bh is not necessary
  296. ;**    mov    eax,ebp    ; get u, v
  297. ;**    shr    eax,26    ; shift out all but int(v)
  298. ;**    shld    ax,bp,6    ; shift in u, shifting up v
  299. ;**
  300. ;**    add    ebp,edx    ; u += du, v += dv
  301. ;**
  302. ;**    mov    al,[esi+eax]    ; get pixel from source bitmap
  303. ;**    mov    ah,bh    ; get lighting table
  304. ;**    mov    al,[ecx+eax]    ; xlat pixel through lighting tables
  305. ;**    mov    [edi],al    ; write pixel...
  306. ;**    inc    edi    ; ...and advance
  307.  
  308.  
  309.   if ALLOW_DITHERING
  310.  
  311. ; dithering
  312. ; loop contains two iterations which must be the same length
  313.     mov    eax,ebp    ; get u, v
  314.     shr    eax,26    ; shift out all but int(v)
  315.     shld    ax,bp,6    ; shift in u, shifting up v
  316.  
  317.     add    ebp,edx    ; u += du, v += dv
  318.  
  319.     mov    al,[esi+eax]    ; get pixel from source bitmap
  320.     mov    ah,bh    ; get lighting table
  321.     add    ebx,_fx_dl_dx1    ; update lighting value
  322.     mov    al,[ecx+eax]    ; xlat pixel through lighting tables
  323.     mov    [edi],al    ; write pixel...
  324.     inc    edi    ; ...and advance
  325.  
  326. ; second iteration
  327.     mov    eax,ebp    ; get u, v
  328.     shr    eax,26    ; shift out all but int(v)
  329.     shld    ax,bp,6    ; shift in u, shifting up v
  330.  
  331.     add    ebp,edx    ; u += du, v += dv
  332.  
  333.     mov    al,[esi+eax]    ; get pixel from source bitmap
  334.     mov    ah,bh    ; get lighting table
  335.     add    ebx,_fx_dl_dx2    ; update lighting value
  336.     mov    al,[ecx+eax]    ; xlat pixel through lighting tables
  337.     mov    [edi],al    ; write pixel...
  338.     inc    edi    ; ...and advance
  339.   else
  340.     mov    eax,ebp    ; get u, v
  341.     shr    eax,26    ; shift out all but int(v)
  342.     shld    ax,bp,6    ; shift in u, shifting up v
  343.  
  344.     add    ebp,edx    ; u += du, v += dv
  345.  
  346.     mov    al,[esi+eax]    ; get pixel from source bitmap
  347.     mov    ah,bh    ; get lighting table
  348.     add    ebx,_fx_dl_dx    ; update lighting value
  349.     mov    al,[ecx+eax]    ; xlat pixel through lighting tables
  350.     mov    [edi],al    ; write pixel...
  351.     inc    edi    ; ...and advance
  352.   endif
  353.  
  354.  
  355.   else
  356.  
  357. ;obsolete: ; version which assumes segment overrides are in place (which they are obviously not)
  358. ;obsolete:     mov    eax,ebp    ; get u, v
  359. ;obsolete:     shr    eax,26    ; shift out all but int(v)
  360. ;obsolete:     shld    ax,bp,6    ; shift in u, shifting up v
  361. ;obsolete: 
  362. ;obsolete:     add    ebp,edx    ; u += du, v += dv
  363. ;obsolete: 
  364. ;obsolete:     mov    al,[eax]    ; get pixel from source bitmap
  365. ;obsolete:     mov    ah,bh    ; get lighting table
  366. ;obsolete:     add    ebx,esi    ; update lighting value
  367. ;obsolete:     mov    al,[eax]    ; xlat pixel through lighting tables
  368. ;obsolete:     mov    [edi],al    ; write pixel...
  369. ;obsolete:     inc    edi    ; ...and advance
  370.  endif
  371.   endm
  372.  
  373. _end1:
  374.  
  375. ; now do the leftover pixel
  376.     mov    eax,ebp
  377.     shr    eax,26    ; shift in v coordinate
  378.     shld    ax,bp,6    ; shift in u coordinate while shifting up v coordinate
  379.     mov    al,[esi+eax]    ; get pixel from source bitmap
  380.     mov    ah,bh    ; get lighting table
  381.  or ah,ah
  382.  jns ok1
  383.  sub ah,ah
  384. ok1:
  385.     mov    al,_lighting_tables[eax]    ; xlat pixel through lighting tables
  386.     mov    [edi],al    ; write pixel...
  387.  
  388. _none_to_do:    popa
  389.     pop    fs
  390.     pop    es
  391.     ret
  392.  
  393.   endif
  394. ; -- Code to get rgb 5 bits integer, 5 bits fraction value into 5 bits integer (for each gun)
  395. ; suitable for inverse color lookup
  396. ;**__test:
  397. ;** int 3
  398. ;**;                  rrrrrfffffrrrrrfffffxxbbbbbfffff
  399. ;**    mov    eax,11111001001010101110101101110111b
  400. ;**    and    eax,11111000001111100000001111100000b
  401. ;**    shld    ebx,eax,15
  402. ;**    or    bx,ax
  403.  
  404.  
  405. ;; esi, ecx should be free
  406. do_transparency_ll:
  407.     mov    esi,_fx_dl_dx
  408.  
  409.     mov    ecx,_loop_count
  410.     inc    ecx
  411.     shr    ecx,1
  412.     je    one_more_pix2
  413.     pushf
  414.  
  415.     align    4
  416.  
  417. loop1a:
  418.     mov    eax,ebp    ; get u, v
  419.     shr    eax,26    ; shift out all but int(v)
  420.     shld    ax,bp,6    ; shift in u, shifting up v
  421.  
  422.     add    ebp,edx    ; u += du, v += dv
  423.  
  424.     mov    al,es:[eax]    ; get pixel from source bitmap
  425.     cmp    al,255
  426.     je    skip1a
  427.     mov    ah,bh    ; get lighting table
  428.     add    ebx,esi    ; _fx_dl_dx    ; update lighting value
  429.     mov    al,fs:[eax]    ; xlat pixel through lighting tables
  430.     mov    [edi],al    ; write pixel...
  431. skip1a:    inc    edi    ; ...and advance
  432.  
  433. ; --- ---
  434.  
  435.     mov    eax,ebp    ; get u, v
  436.     shr    eax,26    ; shift out all but int(v)
  437.     shld    ax,bp,6    ; shift in u, shifting up v
  438.  
  439.     add    ebp,edx    ; u += du, v += dv
  440.  
  441.     mov    al,es:[eax]    ; get pixel from source bitmap
  442.     cmp    al,255
  443.     je    skip2a
  444.     mov    ah,bh    ; get lighting table
  445.     add    ebx,esi    ; _fx_dl_dx    ; update lighting value
  446.     mov    al,fs:[eax]    ; xlat pixel through lighting tables
  447.     mov    [edi],al    ; write pixel...
  448. skip2a:    inc    edi    ; ...and advance
  449.  
  450.     dec    ecx    ; _loop_count
  451.     jne    loop1a
  452.  
  453.     popf
  454.     jnc    all_done_1
  455.  
  456. one_more_pix2:    mov    eax,ebp    ; get u, v
  457.     shr    eax,26    ; shift out all but int(v)
  458.     shld    ax,bp,6    ; shift in u, shifting up v
  459.  
  460.     mov    al,es:[eax]    ; get pixel from source bitmap
  461.     cmp    al,255
  462.     je    skip3a
  463.     mov    ah,bh    ; get lighting table
  464.     mov    al,fs:[eax]    ; xlat pixel through lighting tables
  465.     mov    [edi],al    ; write pixel...
  466.  
  467. skip3a:
  468. all_done_1:    popa
  469.     pop    fs
  470.     pop    es
  471.     ret
  472.  
  473. _TEXT    ends
  474.  
  475.     end
  476. 
  477.