home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / texmap / tmap_16.asm < prev    next >
Assembly Source File  |  1998-06-08  |  7KB  |  250 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_16.asm $
  13. ; $Revision: 1.4 $
  14. ; $Author: mike $
  15. ; $Date: 1994/11/30 00:56:32 $
  16. ;
  17. ; 16 bits per pixel texture mapper
  18. ;
  19. ; $Log: tmap_16.asm $
  20. ; Revision 1.4  1994/11/30  00:56:32  mike
  21. ; optimization.
  22. ; Revision 1.3  1994/11/12  16:39:16  mike
  23. ; jae to ja.
  24. ; Revision 1.2  1993/11/22  10:23:49  mike
  25. ; *** empty log message ***
  26. ; Revision 1.1  1993/09/08  17:29:17  mike
  27. ; Initial revision
  28. ;
  29. ;
  30.  
  31.     .386
  32.  
  33.     public    asm_tmap_scanline_lin_16_
  34.  
  35.     include    tmap_inc.asm
  36.  
  37. _DATA    SEGMENT DWORD PUBLIC USE32 'DATA'
  38.  
  39.     extrn    _fx_u:dword
  40.     extrn    _fx_v:dword
  41.     extrn    _fx_du_dx:dword
  42.     extrn    _fx_dv_dx:dword
  43.     extrn    _fx_y:dword
  44.     extrn    _fx_xleft:dword
  45.     extrn    _fx_xright:dword
  46.  
  47.     extrn    _pixptr:dword
  48.  
  49.     extrn    _x:dword
  50.     extrn    _loop_count:dword
  51.  
  52.  
  53. _DATA    ENDS
  54.  
  55. DGROUP    GROUP    _DATA
  56.  
  57. _TEXT   SEGMENT PARA PUBLIC USE32 'CODE'
  58.  
  59.     ASSUME    DS:_DATA
  60.     ASSUME    CS:_TEXT
  61.  
  62. ; --------------------------------------------------------------------------------------------------
  63. ; Enter:
  64. ;    _xleft    fixed point left x coordinate
  65. ;    _xright    fixed point right x coordinate
  66. ;    _y    fixed point y coordinate
  67. ;    _pixptr    address of source pixel map
  68. ;    _u    fixed point initial u coordinate
  69. ;    _v    fixed point initial v coordinate
  70. ;    _du_dx    fixed point du/dx
  71. ;    _dv_dx    fixed point dv/dx
  72.  
  73. ;   for (x = (int) xleft; x <= (int) xright; x++) {
  74. ;      _setcolor(read_pixel_from_tmap(srcb,((int) (u/z)) & 63,((int) (v/z)) & 63));
  75. ;      _setpixel(x,y);
  76. ;
  77. ;      u += du_dx;
  78. ;      v += dv_dx;
  79. ;      z += dz_dx;
  80. ;   }
  81.  
  82.     align    4
  83. asm_tmap_scanline_lin_16_:
  84.     pusha
  85.  
  86. ; Setup for loop:    _loop_count  iterations = (int) xright - (int) xleft
  87. ;    esi    source pixel pointer = pixptr
  88. ;    edi    initial row pointer = y*320+x
  89.  
  90. ; set esi = pointer to start of texture map data
  91.     mov    esi,_pixptr
  92.  
  93. ; set edi = address of first pixel to modify
  94.     mov    edi,_fx_y
  95.     cmp    edi,_window_bottom
  96.     ja    _none_to_do
  97.  
  98.     sub    edi,_window_top
  99.     imul    edi,_bytes_per_row
  100.  
  101.     mov    eax,_fx_xleft
  102.     sar    eax,16
  103.     jns    eax_ok
  104.     sub    eax,eax
  105. eax_ok:
  106.     sub    eax,_window_left
  107.  
  108.     add    edi,eax
  109.     add    edi,eax    ; add again because it's 2 bytes/pixel
  110.     add    edi,write_buffer
  111.  
  112. ; set _loop_count = # of iterations
  113.     mov    eax,_fx_xright
  114.     sar    eax,16
  115.     cmp    eax,_window_right
  116.     jb    eax_ok1
  117.     mov    eax,_window_right
  118. eax_ok1:    cmp    eax,_window_left
  119.     ja    eax_ok2
  120.     mov    eax,_window_left
  121. eax_ok2:
  122.  
  123.     mov    ebx,_fx_xleft
  124.     sar    ebx,16
  125.     sub    eax,ebx
  126.     js    _none_to_do
  127.     cmp    eax,_window_width
  128.     jbe    _ok_to_do
  129.     mov    eax,_window_width
  130. _ok_to_do:
  131.     mov    _loop_count,eax
  132.  
  133. ;    edi    destination pixel pointer
  134.  
  135.  
  136.     mov    ebx,_fx_u
  137.     mov    ecx,_fx_du_dx
  138.     mov    edx,_fx_dv_dx
  139.     mov    ebp,_fx_v
  140.  
  141.     shl    ebx,10
  142.     shl    ebp,10
  143.     shl    edx,10
  144.     shl    ecx,10
  145.  
  146. ; eax    work
  147. ; ebx    u
  148. ; ecx    du_dx
  149. ; edx    dv_dx
  150. ; ebp    v
  151. ; esi    read address
  152. ; edi    write address
  153.  
  154. _size = (_end1 - _start1)/num_iters
  155.     mov    eax,num_iters-1
  156.     sub    eax,_loop_count
  157.     imul    eax,eax,dword ptr _size
  158.     add    eax,offset _start1
  159.     jmp    eax
  160.  
  161.     align    4
  162. _start1:
  163.  
  164. ; "OPTIMIZATIONS" maybe not worth making
  165. ;    Getting rid of the esi from the mov al,[esi+eax] instruction.
  166. ;       This would require moving into eax at the top of the loop, rather than doing the sub eax,eax.
  167. ;       You would have to align your bitmaps so that the two shlds would create the proper base address.
  168. ;       In other words, your bitmap data would have to begin at 4096x (for 64x64 bitmaps).
  169. ;       I did timings without converting the sub to a mov eax,esi and setting esi to the proper value.
  170. ;       There was a speedup of about 1% to 1.5% without converting the sub to a mov.
  171. ;    Getting rid of the edi by doing a mov nnnn[edi],al instead of mov [edi],al.
  172. ;       The problem with this is you would have a dword offset for nnnn.  My timings indicate it is slower.  (I think.)
  173. ;    Combining u,v and du,dv into single longwords.
  174. ;       The problem with this is you then must do a 16 bit operation to extract them, and you don't have enough
  175. ;       instructions to separate a destination operand from being used by the next instruction.  It shaves out one
  176. ;       register instruction (an add reg,reg), but adds a 16 bit operation, and the setup is more complicated.
  177. ; usage:
  178. ;    eax    work
  179. ;    ebx    u coordinate
  180. ;    ecx    delta u
  181. ;    edx    delta v
  182. ;    ebp    v coordinate
  183. ;    esi    pointer to source bitmap
  184. ;    edi    write address
  185.  rept num_iters
  186.     mov    eax,ebp    ; clear for 
  187.     add    ebp,edx    ; update v coordinate
  188.     shr    eax,26    ; shift in v coordinate
  189.     shld    eax,ebx,6    ; shift in u coordinate while shifting up v coordinate
  190.     add    ebx,ecx    ; update u coordinate
  191.     mov    ax,[esi+2*eax]    ; get pixel from source bitmap
  192.     mov    [edi],ax
  193.     add    edi,2
  194.  
  195. ; inner loop if bitmaps are 256x256
  196. ; your register usage is bogus, and you must clear ecx
  197. ; fix your setup
  198. ; this is only about 10% faster in the inner loop
  199. ; this method would adapt to writing two pixels at a time better than
  200. ; the 64x64 method because you wouldn't run out of registers
  201. ; Note that this method assumes that both dv_dx and du_dx are in edx.
  202. ; edx = vi|vf|ui|uf
  203. ; where each field is 8 bits, vi = integer v coordinate, vf = fractional v coordinate, etc.
  204. ;** add ebx,edx
  205. ;** mov cl,bh
  206. ;** shld cx,bx,8
  207. ;** mov al,[esi+ecx]
  208. ;** mov [edi],al
  209. ;** inc edi
  210.  endm
  211.  
  212. _end1:
  213.  
  214. _none_to_do:    popa
  215.  
  216.     ret
  217.  
  218. _TEXT    ends
  219.  
  220.     end
  221.  
  222.  
  223.  
  224. ; This is the inner loop to write two pixels at a time
  225. ; This is about 2.5% faster overall (on Mike's 66 MHz 80486 DX2, VLB)
  226. ; You must write code to even align edi and do half as many iterations, and write
  227. ; the beginning and ending extra pixels, if necessary.
  228. ;    sub    eax,eax    ; clear for 
  229. ;    shld    eax,ebp,6    ; shift in v coordinate
  230. ;    add    ebp,_fx_dv_dx    ; update v coordinate
  231. ;    shld    eax,ebx,6    ; shift in u coordinate while shifting up v coordinate
  232. ;    add    ebx,ecx    ; update u coordinate
  233. ;    mov    dl,[esi+eax]    ; get pixel from source bitmap
  234. ;
  235. ;    sub    eax,eax    ; clear for 
  236. ;    shld    eax,ebp,6    ; shift in v coordinate
  237. ;    add    ebp,_fx_dv_dx    ; update v coordinate
  238. ;    shld    eax,ebx,6    ; shift in u coordinate while shifting up v coordinate
  239. ;    add    ebx,ecx    ; update u coordinate
  240. ;    mov    dh,[esi+eax]    ; get pixel from source bitmap
  241. ;
  242. ;    mov    [edi],dx
  243. ;    add    edi,2
  244.  
  245.  
  246.