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