home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / 2d / linear.asm < prev    next >
Assembly Source File  |  1998-06-08  |  40KB  |  860 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/2d/rcs/linear.asm $
  13. ; $Revision: 1.20 $
  14. ; $Author: john $
  15. ; $Date: 1994/11/28 17:08:30 $
  16. ;
  17. ; Routines to access linear VGA memory
  18. ;
  19. ; $Log: linear.asm $
  20. ; Revision 1.20  1994/11/28  17:08:30  john
  21. ; Took out some unused functions in linear.asm, moved
  22. ; gr_linear_movsd from linear.asm to bitblt.c, made sure that
  23. ; the code in ibiblt.c sets the direction flags before rep movsing.
  24. ; Revision 1.19  1994/11/27  22:57:56  john
  25. ; Took out some code that was never called.
  26. ; Revision 1.18  1994/09/12  14:40:16  john
  27. ; Neatend.
  28. ; Revision 1.17  1994/07/27  18:30:30  john
  29. ; Took away the blending table.
  30. ; Revision 1.16  1994/04/08  16:59:28  john
  31. ; Add fading poly's; Made palette fade 32 instead of 16.
  32. ; Revision 1.15  1993/12/21  20:10:03  john
  33. ; *** empty log message ***
  34. ; Revision 1.14  1993/12/21  19:58:31  john
  35. ; added selector stuff
  36. ; Revision 1.13  1993/12/21  11:40:51  john
  37. ; *** empty log message ***
  38. ; Revision 1.12  1993/12/09  15:01:52  john
  39. ; Changed palette stuff majorly
  40. ; Revision 1.11  1993/12/08  16:41:02  john
  41. ; *** empty log message ***
  42. ; Revision 1.10  1993/12/08  11:50:17  john
  43. ; Fixed bug with gr_init
  44. ; Revision 1.9  1993/12/07  12:32:12  john
  45. ; moved bmd_palette to gr_palette
  46. ; Revision 1.8  1993/12/03  12:11:25  john
  47. ; *** empty log message ***
  48. ; Revision 1.7  1993/11/16  11:29:08  john
  49. ; *** empty log message ***
  50. ; Revision 1.6  1993/10/15  16:22:13  john
  51. ; *** empty log message ***
  52. ; Revision 1.5  1993/09/29  16:15:28  john
  53. ; added assembler linear_line
  54. ; Revision 1.4  1993/09/26  18:59:27  john
  55. ; fade stuff
  56. ; Revision 1.3  1993/09/21  14:00:59  john
  57. ; added code to save 43/50 line text modes.
  58. ; Revision 1.2  1993/09/16  17:28:06  john
  59. ; added code to save/restore video mode
  60. ; Revision 1.1  1993/09/08  11:41:30  john
  61. ; Initial revision
  62. ;
  63. ;
  64.  
  65.  
  66. .386
  67.  
  68.  
  69.  
  70. _DATA   SEGMENT BYTE PUBLIC USE32 'DATA'
  71.  
  72.  
  73. INCLUDE VGAREGS.INC
  74.  
  75.  
  76.         ; Put data here
  77.  
  78.         PUBLIC _gr_var_color
  79.         PUBLIC _gr_var_bitmap
  80.         PUBLIC _gr_var_bwidth
  81.         _gr_var_color   dd  ?
  82.         _gr_var_bitmap  dd  ?
  83.         _gr_var_bwidth  dd  ?
  84.  
  85.         ; Local variables for gr_linear_line_
  86.         AdjUp           dd  ?   ;error term adjust up on each advance
  87.         AdjDown         dd  ?   ;error term adjust down when error term turns over
  88.         WholeStep       dd  ?   ;minimum run length
  89.         XAdvance        dd  ?   ;1 or -1, for direction in which X advances
  90.         XStart          dd  ?
  91.         YStart          dd  ?
  92.         XEnd            dd  ?
  93.         YEnd            dd  ?
  94.  
  95.  
  96. _DATA   ENDS
  97.  
  98. DGROUP  GROUP _DATA
  99.  
  100.  
  101. _TEXT   SEGMENT BYTE PUBLIC USE32 'CODE'
  102.  
  103.         ASSUME  DS:_DATA
  104.         ASSUME  CS:_TEXT
  105.  
  106.         include psmacros.inc
  107.         ; Args passed in EAX, EDX, EBX, ECX
  108.  
  109.  
  110. ; Fast run length slice line drawing implementation for mode 0x13, the VGA's
  111. ; 320x200 256-color mode.
  112. ; Draws a line between the specified endpoints in color Color.
  113.  
  114.  
  115. PUBLIC gr_linear_line_
  116. gr_linear_line_:
  117.  
  118.     cld
  119.  
  120.     push    esi  ;preserve C register variables
  121.     push    edi
  122.     push    ebp
  123.  
  124.     mov     XStart, eax
  125.     mov     YStart, edx
  126.     mov     XEnd, ebx
  127.     mov     YEnd, ecx
  128.  
  129.     mov     ebp, _gr_var_bwidth
  130.  
  131. ; We'll draw top to bottom, to reduce the number of cases we have to handle,
  132. ; and to make lines between the same endpoints always draw the same pixels.
  133.  
  134.     mov     eax,YStart
  135.     cmp     eax,YEnd
  136.     jle     LineIsTopToBottom
  137.     xchg    YEnd, eax    ;swap endpoints
  138.     mov     YStart, eax
  139.     mov     ebx, XStart
  140.     xchg    XEnd, ebx
  141.     mov     XStart, ebx
  142.  
  143. LineIsTopToBottom:
  144.  
  145. ; Point EDI to the first pixel to draw.
  146.     mov     edx,ebp
  147.     mul     edx             ;YStart * ebp
  148.     mov     esi, XStart
  149.     mov     edi, esi
  150.     add     edi, _gr_var_bitmap
  151.     add     edi, eax        ;EDI = YStart * ebp + XStart
  152.                             ; = offset of initial pixel
  153.  
  154. ; Figure out how far we're going vertically (guaranteed to be positive).
  155.     mov     ecx, YEnd
  156.     sub     ecx, YStart     ;ECX = YDelta
  157.  
  158. ; Figure out whether we're going left or right, and how far we're going
  159. ; horizontally. In the process, special-case vertical lines, for speed and
  160. ; to avoid nasty boundary conditions and division by 0.
  161.  
  162.     mov     edx, XEnd
  163.     sub     edx, esi        ;XDelta
  164.     jnz     NotVerticalLine ;XDelta == 0 means vertical line
  165.                             ;it is a vertical line
  166.                             ;yes, special case vertical line
  167.  
  168.     mov     eax, _gr_var_color
  169. VLoop:
  170.     mov     [edi],al
  171.     add     edi,ebp
  172.     dec     ecx
  173.     jns     VLoop
  174.     jmp     Done
  175.  
  176. ; Special-case code for horizontal lines.
  177.  
  178. IsHorizontalLine:
  179.     mov     eax, _gr_var_color
  180.     mov     ah,al           ;duplicate in high byte for word access
  181.     and     ebx,ebx         ;left to right?
  182.     jns     DirSet          ;yes
  183.     sub     edi, edx        ;currently right to left, point to left end so we
  184.                             ; can go left to right (avoids unpleasantness with
  185.                             ; right to left REP STOSW)
  186. DirSet:
  187.     mov     ecx, edx
  188.     inc     ecx             ;# of pixels to draw
  189.  
  190.     shr     ecx, 1          ;# of words to draw
  191.     rep     stosw           ;do as many words as possible
  192.     adc     ecx, ecx
  193.     rep     stosb           ;do the odd byte, if there is one
  194.  
  195.     jmp     Done
  196.  
  197. ; Special-case code for diagonal lines.
  198.  
  199. IsDiagonalLine:
  200.     mov     eax, _gr_var_color
  201.     add     ebx, ebp    ;advance distance from one pixel to next
  202.  
  203. DLoop:
  204.     mov     [edi],al
  205.     add     edi, ebx
  206.     dec     ecx
  207.     jns     DLoop
  208.     jmp     Done
  209.  
  210. NotVerticalLine:
  211.     mov     ebx,1               ;assume left to right, so XAdvance = 1
  212.                                 ;***leaves flags unchanged***
  213.     jns     LeftToRight         ;left to right, all set
  214.     neg     ebx                 ;right to left, so XAdvance = -1
  215.     neg     edx                 ;|XDelta|
  216.  
  217. LeftToRight:
  218. ; Special-case horizontal lines.
  219.  
  220.     and     ecx, ecx            ;YDelta == 0?
  221.     jz      IsHorizontalLine    ;yes
  222.  
  223. ; Special-case diagonal lines.
  224.     cmp     ecx, edx            ;YDelta == XDelta?
  225.     jz      IsDiagonalLine      ;yes
  226.  
  227. ; Determine whether the line is X or Y major, and handle accordingly.
  228.     cmp     edx, ecx
  229.     jae     XMajor
  230.     jmp     YMajor
  231.  
  232. ; X-major (more horizontal than vertical) line.
  233.  
  234. XMajor:
  235.         and     ebx,ebx         ;left to right?
  236.         jns     DFSet           ;yes, CLD is already set
  237.     std                     ;right to left, so draw backwards
  238. DFSet:
  239.         mov     eax,edx         ;XDelta
  240.         sub     edx,edx         ;prepare for division
  241.         div     ecx             ;EAX = XDelta/YDelta
  242.                 ; (minimum # of pixels in a run in this line)
  243.                                 ;EDX = XDelta % YDelta
  244.         mov     ebx,edx         ;error term adjust each time Y steps by 1;
  245.         add     ebx,ebx         ; used to tell when one extra pixel should be
  246.         mov     AdjUp, ebx      ; drawn as part of a run, to account for
  247.                 ; fractional steps along the X axis per
  248.                 ; 1-pixel steps along Y
  249.         mov     esi, ecx        ;error term adjust when the error term turns
  250.         add     esi, esi        ; over, used to factor out the X step made at
  251.         mov     AdjDown, esi    ; that time
  252.  
  253. ; Initial error term; reflects an initial step of 0.5 along the Y axis.
  254.         sub     edx, esi        ;(XDelta % YDelta) - (YDelta * 2)
  255.                 ;DX = initial error term
  256. ; The initial and last runs are partial, because Y advances only 0.5 for
  257. ; these runs, rather than 1. Divide one full run, plus the initial pixel,
  258. ; between the initial and last runs.
  259.         mov     esi, ecx        ;SI = YDelta
  260.         mov     ecx, eax        ;whole step (minimum run length)
  261.         shr     ecx,1
  262.         inc     ecx             ;initial pixel count = (whole step / 2) + 1;
  263.                 ; (may be adjusted later). This is also the
  264.         ; final run pixel count
  265.         push    ecx             ;remember final run pixel count for later
  266. ; If the basic run length is even and there's no fractional advance, we have
  267. ; one pixel that could go to either the initial or last partial run, which
  268. ; we'll arbitrarily allocate to the last run.
  269. ; If there is an odd number of pixels per run, we have one pixel that can't
  270. ; be allocated to either the initial or last partial run, so we'll add 0.5 to
  271. ; the error term so this pixel will be handled by the normal full-run loop.
  272.         add     edx,esi         ;assume odd length, add YDelta to error term
  273.         ; (add 0.5 of a pixel to the error term)
  274.     test    al,1            ;is run length even?
  275.     jnz     XMajorAdjustDone ;no, already did work for odd case, all set
  276.         sub     edx,esi         ;length is even, undo odd stuff we just did
  277.         and     ebx,ebx         ;is the adjust up equal to 0?
  278.     jnz     XMajorAdjustDone ;no (don't need to check for odd length,
  279.                                 ; because of the above test)
  280.         dec     ecx             ;both conditions met; make initial run 1
  281.                 ; shorter
  282.  
  283. XMajorAdjustDone:
  284.         mov     WholeStep,eax   ;whole step (minimum run length)
  285.         mov     eax, _gr_var_color       ;AL = drawing color
  286. ; Draw the first, partial run of pixels.
  287.     rep     stosb           ;draw the final run
  288.         add     edi,ebp ;advance along the minor axis (Y)
  289. ; Draw all full runs.
  290.         cmp     esi,1           ;are there more than 2 scans, so there are
  291.                                 ; some full runs? (SI = # scans - 1)
  292.     jna     XMajorDrawLast  ;no, no full runs
  293.         dec     edx             ;adjust error term by -1 so we can use
  294.                 ; carry test
  295.         shr     esi,1           ;convert from scan to scan-pair count
  296.     jnc     XMajorFullRunsOddEntry  ;if there is an odd number of scans,
  297.                     ; do the odd scan now
  298. XMajorFullRunsLoop:
  299.         mov     ecx, WholeStep  ;run is at least this long
  300.         add     edx,ebx         ;advance the error term and add an extra
  301.     jnc     XMajorNoExtra   ; pixel if the error term so indicates
  302.         inc     ecx             ;one extra pixel in run
  303.         sub     edx,AdjDown     ;reset the error term
  304. XMajorNoExtra:
  305.         rep     stosb           ;draw this scan line's run
  306.         add     edi,ebp ;advance along the minor axis (Y)
  307. XMajorFullRunsOddEntry:         ;enter loop here if there is an odd number
  308.                 ; of full runs
  309.         mov     ecx,WholeStep   ;run is at least this long
  310.         add     edx,ebx         ;advance the error term and add an extra
  311.     jnc     XMajorNoExtra2  ; pixel if the error term so indicates
  312.         inc     ecx             ;one extra pixel in run
  313.         sub     edx,AdjDown     ;reset the error term
  314. XMajorNoExtra2:
  315.         rep     stosb           ;draw this scan line's run
  316.         add     edi,ebp ;advance along the minor axis (Y)
  317.  
  318.         dec     esi
  319.     jnz     XMajorFullRunsLoop
  320. ; Draw the final run of pixels.
  321. XMajorDrawLast:
  322.         pop     ecx             ;get back the final run pixel length
  323.     rep     stosb           ;draw the final run
  324.  
  325.     cld                     ;restore normal direction flag
  326.     jmp     Done
  327. ; Y-major (more vertical than horizontal) line.
  328. YMajor:
  329.         mov     XAdvance,ebx    ;remember which way X advances
  330.         mov     eax,ecx         ;YDelta
  331.         mov     ecx,edx         ;XDelta
  332.         sub     edx,edx         ;prepare for division
  333.         div     ecx             ;EAX = YDelta/XDelta
  334.                 ; (minimum # of pixels in a run in this line)
  335.                                 ;EDX = YDelta % XDelta
  336.         mov     ebx,edx         ;error term adjust each time X steps by 1;
  337.         add     ebx,ebx         ; used to tell when one extra pixel should be
  338.         mov     AdjUp,ebx       ; drawn as part of a run, to account for
  339.                 ; fractional steps along the Y axis per
  340.                 ; 1-pixel steps along X
  341.         mov     esi,ecx         ;error term adjust when the error term turns
  342.         add     esi,esi         ; over, used to factor out the Y step made at
  343.         mov     AdjDown, esi    ; that time
  344.  
  345. ; Initial error term; reflects an initial step of 0.5 along the X axis.
  346.         sub     edx,esi         ;(YDelta % XDelta) - (XDelta * 2)
  347.                 ;DX = initial error term
  348. ; The initial and last runs are partial, because X advances only 0.5 for
  349. ; these runs, rather than 1. Divide one full run, plus the initial pixel,
  350. ; between the initial and last runs.
  351.         mov     esi,ecx         ;SI = XDelta
  352.         mov     ecx,eax         ;whole step (minimum run length)
  353.         shr     ecx,1
  354.         inc     ecx             ;initial pixel count = (whole step / 2) + 1;
  355.                 ; (may be adjusted later)
  356.         push    ecx             ;remember final run pixel count for later
  357.  
  358. ; If the basic run length is even and there's no fractional advance, we have
  359. ; one pixel that could go to either the initial or last partial run, which
  360. ; we'll arbitrarily allocate to the last run.
  361. ; If there is an odd number of pixels per run, we have one pixel that can't
  362. ; be allocated to either the initial or last partial run, so we'll add 0.5 to
  363. ; the error term so this pixel will be handled by the normal full-run loop.
  364.         add     edx,esi         ;assume odd length, add XDelta to error term
  365.     test    al,1            ;is run length even?
  366.     jnz     YMajorAdjustDone ;no, already did work for odd case, all set
  367.         sub     edx,esi         ;length is even, undo odd stuff we just did
  368.         and     ebx,ebx         ;is the adjust up equal to 0?
  369.     jnz     YMajorAdjustDone ;no (don't need to check for odd length,
  370.          ; because of the above test)
  371.         dec     ecx             ;both conditions met; make initial run 1
  372.                 ; shorter
  373. YMajorAdjustDone:
  374.         mov     WholeStep,eax   ;whole step (minimum run length)
  375.         mov     eax,_gr_var_color        ;AL = drawing color
  376.         mov     ebx, XAdvance   ;which way X advances
  377.  
  378. ; Draw the first, partial run of pixels.
  379. YMajorFirstLoop:
  380.         mov     [edi],al        ;draw the pixel
  381.         add     edi,ebp ;advance along the major axis (Y)
  382.         dec     ecx
  383.     jnz     YMajorFirstLoop
  384.         add     edi,ebx           ;advance along the minor axis (X)
  385. ; Draw all full runs.
  386.         cmp     esi,1            ;# of full runs. Are there more than 2
  387.         ; columns, so there are some full runs?
  388.         ; (SI = # columns - 1)
  389.     jna     YMajorDrawLast  ;no, no full runs
  390.         dec     edx              ;adjust error term by -1 so we can use
  391.                 ; carry test
  392.         shr     esi,1            ;convert from column to column-pair count
  393.     jnc     YMajorFullRunsOddEntry  ;if there is an odd number of
  394.                     ; columns, do the odd column now
  395. YMajorFullRunsLoop:
  396.         mov     ecx,WholeStep   ;run is at least this long
  397.         add     edx,AdjUp       ;advance the error term and add an extra
  398.     jnc     YMajorNoExtra   ; pixel if the error term so indicates
  399.         inc     ecx              ;one extra pixel in run
  400.         sub     edx,AdjDown     ;reset the error term
  401. YMajorNoExtra:
  402.                 ;draw the run
  403. YMajorRunLoop:
  404.         mov     [edi],al        ;draw the pixel
  405.         add     edi,ebp ;advance along the major axis (Y)
  406.         dec     ecx
  407.     jnz     YMajorRunLoop
  408.         add     edi,ebx         ;advance along the minor axis (X)
  409. YMajorFullRunsOddEntry:         ;enter loop here if there is an odd number
  410.                 ; of full runs
  411.         mov     ecx,WholeStep   ;run is at least this long
  412.         add     edx,AdjUp       ;advance the error term and add an extra
  413.     jnc     YMajorNoExtra2  ; pixel if the error term so indicates
  414.         inc     ecx              ;one extra pixel in run
  415.         sub     edx, AdjDown    ;reset the error term
  416. YMajorNoExtra2:
  417.                 ;draw the run
  418. YMajorRunLoop2:
  419.         mov     [edi],al         ;draw the pixel
  420.         add     edi,ebp ;advance along the major axis (Y)
  421.         dec     ecx
  422.     jnz     YMajorRunLoop2
  423.         add     edi,ebx           ;advance along the minor axis (X)
  424.  
  425.         dec     esi
  426.     jnz     YMajorFullRunsLoop
  427. ; Draw the final run of pixels.
  428. YMajorDrawLast:
  429.         pop     ecx              ;get back the final run pixel length
  430. YMajorLastLoop:
  431.         mov     [edi],al         ;draw the pixel
  432.         add     edi,ebp ;advance along the major axis (Y)
  433.         dec     ecx
  434.     jnz     YMajorLastLoop
  435. Done:
  436.     pop ebp
  437.     pop edi
  438.     pop esi  ;restore C register variables
  439.     ret
  440.  
  441. PUBLIC gr_linear_stosd_
  442.  
  443. gr_linear_stosd_:
  444.  
  445.             ; EAX -> Destination buffer
  446.             ; EDX -> Byte to store
  447.             ; EBX -> Number of bytes to move
  448.  
  449.             push    ecx
  450.             push    edi
  451.             mov     edi, eax
  452.             mov     dh, dl
  453.             mov     ax, dx
  454.             shl     eax, 16
  455.             mov     ax, dx
  456.             cld
  457.             mov     ecx, ebx
  458.             shr     ecx, 2
  459.             rep     stosd
  460.             mov     ecx, ebx
  461.             and     ecx, 011b
  462.             rep     stosb
  463.             pop     edi
  464.             pop     ecx
  465.             ret
  466.  
  467. PUBLIC gr_update_buffer_
  468.  
  469. gr_update_buffer_:
  470.  
  471.         ; EAX = Latest source buffer
  472.         ; EDX = Earlier source buffer
  473.         ; EBX = Dest source buffer
  474.         ; ECX = Size of buffer
  475.  
  476.  
  477.         push    esi
  478.         push    edi
  479.         push    ebp
  480.         cld
  481.  
  482.         mov     esi, eax
  483.         mov     edi, edx
  484.  
  485.         mov     ebp, esi
  486.         shr     ecx, 2
  487.  
  488. FindNextMismatch:
  489.         repe    cmpsd
  490.  
  491.         mov     eax, [esi-4]
  492.  
  493.         mov     edx, ebx
  494.         add     edx, esi
  495.         sub     edx, ebp
  496.         mov     [edx], eax       ; EDX = dest + size - bytes to end
  497.  
  498.         cmp     ecx, 0
  499.         jne     FindNextMismatch
  500.  
  501. Done11:
  502.         pop     ebp
  503.         pop     edi
  504.         pop     esi
  505.         ret
  506.  
  507.  
  508. ;--NOT USED!!-- X0  dd  ?               ;X coordinate of line start point
  509. ;--NOT USED!!-- Y0  dd  ?               ;Y coordinate of line start point
  510. ;--NOT USED!!-- X1  dd  ?               ;X coordinate of line end point
  511. ;--NOT USED!!-- Y1  dd  ?               ;Y coordinate of line end point
  512. ;--NOT USED!!-- BaseColor db    ?       ;color # of first color in block used for
  513. ;--NOT USED!!--                                                 ; antialiasing, the 100% intensity version of the
  514. ;--NOT USED!!--                                                 ; drawing color
  515. ;--NOT USED!!-- NumLevels db    16      ;size of color block, with BaseColor+NumLevels-1
  516. ;--NOT USED!!--                                                 ; being the 0% intensity version of the drawing color
  517. ;--NOT USED!!--                                                 ; (maximum NumLevels = 256)
  518. ;--NOT USED!!-- IntensityBits db 4      ;log base 2 of NumLevels; the # of bits used to
  519. ;--NOT USED!!--                                                 ; describe the intensity of the drawing color.
  520. ;--NOT USED!!--                                                 ; 2**IntensityBits==NumLevels
  521. ;--NOT USED!!--                                                 ; (maximum IntensityBits = 8)
  522. ;--NOT USED!!-- ; C near-callable function to draw an antialiased line from
  523. ;--NOT USED!!-- ; (X0,Y0) to (X1,Y1), in mode 13h, the VGA's standard 320x200 256-color
  524. ;--NOT USED!!-- ; mode. Uses an antialiasing approach published by Xiaolin Wu in the July
  525. ;--NOT USED!!-- ; 1991 issue of Computer Graphics. Requires that the palette be set up so
  526. ;--NOT USED!!-- ; that there are NumLevels intensity levels of the desired drawing color,
  527. ;--NOT USED!!-- ; starting at color BaseColor (100% intensity) and followed by (NumLevels-1)
  528. ;--NOT USED!!-- ; levels of evenly decreasing intensity, with color (BaseColor+NumLevels-1)
  529. ;--NOT USED!!-- ; being 0% intensity of the desired drawing color (black). No clipping is
  530. ;--NOT USED!!-- ; performed in DrawWuLine. Handles a maximum of 256 intensity levels per
  531. ;--NOT USED!!-- ; antialiased color. This code is suitable for use at screen resolutions,
  532. ;--NOT USED!!-- ; with lines typically no more than 1K long; for longer lines, 32-bit error
  533. ;--NOT USED!!-- ; arithmetic must be used to avoid problems with fixed-point inaccuracy.
  534. ;--NOT USED!!-- ; Tested with TASM 3.0.
  535. ;--NOT USED!!-- ;
  536. ;--NOT USED!!-- ; C near-callable as:
  537. ;--NOT USED!!-- ;   void DrawWuLine(int X0, int Y0, int X1, int Y1, int BaseColor,
  538. ;--NOT USED!!-- ;       int NumLevels, unsigned int IntensityBits);
  539. ;--NOT USED!!-- 
  540. ;--NOT USED!!-- SCREEN_WIDTH_IN_BYTES equ 320   ;# of bytes from the start of one scan line
  541. ;--NOT USED!!--                                                                 ; to the start of the next
  542. ;--NOT USED!!-- SCREEN_SEGMENT  equ 0a000h  ;segment in which screen memory resides
  543. ;--NOT USED!!-- 
  544. ;--NOT USED!!-- ; Parameters passed in stack frame.
  545. ;--NOT USED!!-- 
  546. ;--NOT USED!!-- 
  547. ;--NOT USED!!--                 ;_gr_var_color, _gr_var_bitmap, _gr_var_bwidth
  548. ;--NOT USED!!-- 
  549. ;--NOT USED!!--                 public  gr_linear_aaline_
  550. ;--NOT USED!!-- gr_linear_aaline_:
  551. ;--NOT USED!!-- 
  552. ;--NOT USED!!--                 push    ebp
  553. ;--NOT USED!!--                 push    esi  ;preserve C's register variables
  554. ;--NOT USED!!--                 push    edi
  555. ;--NOT USED!!--                 cld     ;make string instructions increment their pointers
  556. ;--NOT USED!!-- 
  557. ;--NOT USED!!--                 mov     X0, eax
  558. ;--NOT USED!!--                 mov     Y0, edx
  559. ;--NOT USED!!--                 mov     X1, ebx
  560. ;--NOT USED!!--                 mov     Y1, ecx
  561. ;--NOT USED!!-- 
  562. ;--NOT USED!!--                 mov     eax, _gr_var_color
  563. ;--NOT USED!!--                 mov     BaseColor, al
  564. ;--NOT USED!!-- 
  565. ;--NOT USED!!-- ; Make sure the line runs top to bottom.
  566. ;--NOT USED!!--                 mov     esi,X0
  567. ;--NOT USED!!--                 mov     eax,Y0
  568. ;--NOT USED!!--                 cmp     eax,Y1       ;swap endpoints if necessary to ensure that
  569. ;--NOT USED!!--                 jna     NoSwap      ; Y0 <= Y1
  570. ;--NOT USED!!--                 xchg    Y1,eax
  571. ;--NOT USED!!--                 mov     Y0,eax
  572. ;--NOT USED!!--                 xchg    X1,esi
  573. ;--NOT USED!!--                 mov     X0,esi
  574. ;--NOT USED!!-- NoSwap:
  575. ;--NOT USED!!-- 
  576. ;--NOT USED!!-- ; Draw the initial pixel, which is always exactly intersected by the line
  577. ;--NOT USED!!-- ; and so needs no weighting.
  578. ;--NOT USED!!-- 
  579. ;--NOT USED!!--                 mov     edx,_gr_var_bwidth
  580. ;--NOT USED!!--                 mul     edx         ;Y0 * SCREEN_WIDTH_IN_BYTES yields the offset
  581. ;--NOT USED!!--                                                         ; of the start of the row start the initial
  582. ;--NOT USED!!--                                                         ; pixel is on
  583. ;--NOT USED!!--                 add     esi,eax         ;point DS:SI to the initial pixel
  584. ;--NOT USED!!--                 add     esi,_gr_var_bitmap
  585. ;--NOT USED!!--                 mov     al, BaseColor ;color with which to draw
  586. ;--NOT USED!!--                 mov     [esi],al     ;draw the initial pixel
  587. ;--NOT USED!!-- 
  588. ;--NOT USED!!--                 mov     ebx,1        ;XDir = 1; assume DeltaX >= 0
  589. ;--NOT USED!!--                 mov     ecx,X1
  590. ;--NOT USED!!--                 sub     ecx,X0  ;DeltaX; is it >= 1?
  591. ;--NOT USED!!--                 jns     DeltaXSet   ;yes, move left->right, all set
  592. ;--NOT USED!!--                                                                 ;no, move right->left
  593. ;--NOT USED!!--                 neg     ecx      ;make DeltaX positive
  594. ;--NOT USED!!--                 neg     ebx      ;XDir = -1
  595. ;--NOT USED!!-- DeltaXSet:
  596. ;--NOT USED!!-- 
  597. ;--NOT USED!!-- ; Special-case horizontal, vertical, and diagonal lines, which require no
  598. ;--NOT USED!!-- ; weighting because they go right through the center of every pixel.
  599. ;--NOT USED!!--                 mov     edx,Y1
  600. ;--NOT USED!!--                 sub     edx,Y0  ;DeltaY; is it 0?
  601. ;--NOT USED!!--                 jnz     NotHorz     ;no, not horizontal
  602. ;--NOT USED!!--                                                                 ;yes, is horizontal, special case
  603. ;--NOT USED!!--                 and     ebx,ebx       ;draw from left->right?
  604. ;--NOT USED!!--                 jns     DoHorz      ;yes, all set
  605. ;--NOT USED!!--                 std         ;no, draw right->left
  606. ;--NOT USED!!-- DoHorz:
  607. ;--NOT USED!!--                 lea     edi,[ebx+esi]  ;point DI to next pixel to draw
  608. ;--NOT USED!!--                                                                 ;point ES:DI to next pixel to draw
  609. ;--NOT USED!!--                 mov     al,BaseColor ;color with which to draw
  610. ;--NOT USED!!--                                                                 ;CX = DeltaX at this point
  611. ;--NOT USED!!--                 rep     stosb       ;draw the rest of the horizontal line
  612. ;--NOT USED!!--                 cld                 ;restore default direction flag
  613. ;--NOT USED!!--                 jmp     DoneAA        ;and we're done
  614. ;--NOT USED!!-- 
  615. ;--NOT USED!!-- NotHorz:
  616. ;--NOT USED!!--                 and     ecx,ecx       ;is DeltaX 0?
  617. ;--NOT USED!!--                 jnz     NotVert     ;no, not a vertical line
  618. ;--NOT USED!!--                                                                 ;yes, is vertical, special case
  619. ;--NOT USED!!--                 mov     al,BaseColor ;color with which to draw
  620. ;--NOT USED!!-- VertLoop:
  621. ;--NOT USED!!--                 add     esi,_gr_var_bwidth ;point to next pixel to draw
  622. ;--NOT USED!!--                 mov     [esi], al     ;draw the next pixel
  623. ;--NOT USED!!--                 dec     edx           ;--DeltaY
  624. ;--NOT USED!!--                 jnz     VertLoop
  625. ;--NOT USED!!--                 jmp     DoneAA        ;and we're done
  626. ;--NOT USED!!-- 
  627. ;--NOT USED!!-- NotVert:
  628. ;--NOT USED!!--                 cmp     ecx,edx       ;DeltaX == DeltaY?
  629. ;--NOT USED!!--                 jnz     NotDiag     ;no, not diagonal
  630. ;--NOT USED!!--                                                                 ;yes, is diagonal, special case
  631. ;--NOT USED!!--                 mov     al,BaseColor ;color with which to draw
  632. ;--NOT USED!!-- DiagLoop:
  633. ;--NOT USED!!--                 lea     esi,[esi+ebx]
  634. ;--NOT USED!!--                 add     esi,_gr_var_bwidth
  635. ;--NOT USED!!--                                                                 ;advance to next pixel to draw by
  636. ;--NOT USED!!--                                                                 ; incrementing Y and adding XDir to X
  637. ;--NOT USED!!--                 mov     [esi],al     ;draw the next pixel
  638. ;--NOT USED!!--                 dec     edx      ;--DeltaY
  639. ;--NOT USED!!--                 jnz     DiagLoop
  640. ;--NOT USED!!--                 jmp     DoneAA        ;and we're done
  641. ;--NOT USED!!-- 
  642. ;--NOT USED!!-- ; Line is not horizontal, diagonal, or vertical.
  643. ;--NOT USED!!-- NotDiag:
  644. ;--NOT USED!!-- ; Is this an X-major or Y-major line?
  645. ;--NOT USED!!--                 cmp     edx,ecx
  646. ;--NOT USED!!--                 jb      XMajorAA          ;it's X-major
  647. ;--NOT USED!!-- 
  648. ;--NOT USED!!-- ; It's a Y-major line. Calculate the 16-bit fixed-point fractional part of a
  649. ;--NOT USED!!-- ; pixel that X advances each time Y advances 1 pixel, truncating the result
  650. ;--NOT USED!!-- ; to avoid overrunning the endpoint along the X axis.
  651. ;--NOT USED!!--                 xchg    edx,ecx       ;DX = DeltaX, CX = DeltaY
  652. ;--NOT USED!!--                 sub     ax,ax       ;make DeltaX 16.16 fixed-point value in DX:AX
  653. ;--NOT USED!!--                 div     cx      ;AX = (DeltaX << 16) / DeltaY. Won't overflow
  654. ;--NOT USED!!--                                                                 ; because DeltaX < DeltaY
  655. ;--NOT USED!!--                 mov     di,cx       ;DI = DeltaY (loop count)
  656. ;--NOT USED!!--                 sub     esi,ebx       ;back up the start X by 1, as explained below
  657. ;--NOT USED!!--                 mov     dx,-1       ;initialize the line error accumulator to -1,
  658. ;--NOT USED!!--                                                                 ; so that it will turn over immediately and
  659. ;--NOT USED!!--                                                                 ; advance X to the start X. This is necessary
  660. ;--NOT USED!!--                                                                 ; properly to bias error sums of 0 to mean
  661. ;--NOT USED!!--                                                                 ; "advance next time" rather than "advance
  662. ;--NOT USED!!--                                                                 ; this time," so that the final error sum can
  663. ;--NOT USED!!--                                                                 ; never cause drawing to overrun the final X
  664. ;--NOT USED!!--                                                                 ; coordinate (works in conjunction with
  665. ;--NOT USED!!--                                                                 ; truncating ErrorAdj, to make sure X can't
  666. ;--NOT USED!!--                                                                 ; overrun)
  667. ;--NOT USED!!--                 mov     cl,8           ;CL = # of bits by which to shift
  668. ;--NOT USED!!--                 sub     cl,IntensityBits   ; ErrorAcc to get intensity level (8
  669. ;--NOT USED!!--                                                                                 ; instead of 16 because we work only
  670. ;--NOT USED!!--                                                                                 ; with the high byte of ErrorAcc)
  671. ;--NOT USED!!--                 mov     ch,NumLevels ;mask used to flip all bits in an
  672. ;--NOT USED!!--                 dec     ch             ; intensity weighting, producing
  673. ;--NOT USED!!--                                                                                    ; result (1 - intensity weighting)
  674. ;--NOT USED!!--                 mov     bp, ax
  675. ;--NOT USED!!--                 mov     al, BaseColor
  676. ;--NOT USED!!--                          ;BP = ErrorAdj, AL = BaseColor,
  677. ;--NOT USED!!--                          ; AH = scratch register
  678. ;--NOT USED!!-- 
  679. ;--NOT USED!!-- 
  680. ;--NOT USED!!-- 
  681. ;--NOT USED!!-- ; Draw all remaining pixels.
  682. ;--NOT USED!!-- YMajorLoop:
  683. ;--NOT USED!!--                 add     dx,bp           ;calculate error for next pixel
  684. ;--NOT USED!!--                         jnc     NoXAdvance              ;not time to step in X yet
  685. ;--NOT USED!!--                                                                                                                                                                 ;the error accumulator turned over,
  686. ;--NOT USED!!--                                                                                                                                                                 ; so advance the X coord
  687. ;--NOT USED!!--                                 add     esi,ebx                   ;add XDir to the pixel pointer
  688. ;--NOT USED!!-- NoXAdvance:
  689. ;--NOT USED!!--                                 add     esi,_gr_var_bwidth ;Y-major, so always advance Y
  690. ;--NOT USED!!-- 
  691. ;--NOT USED!!-- ; The IntensityBits most significant bits of ErrorAcc give us the intensity
  692. ;--NOT USED!!-- ; weighting for this pixel, and the complement of the weighting for the
  693. ;--NOT USED!!-- ; paired pixel.
  694. ;--NOT USED!!--                 mov     ah,dh   ;msb of ErrorAcc
  695. ;--NOT USED!!--                 shr     ah,cl   ;Weighting = ErrorAcc >> IntensityShift;
  696. ;--NOT USED!!--                 ;add     ah,al   ;BaseColor + Weighting
  697. ;--NOT USED!!-- 
  698. ;--NOT USED!!--                 ; Make ah =   _gr_fade_table + BaseColor+(15-ah)*256
  699. ;--NOT USED!!--                 push    ecx
  700. ;--NOT USED!!--                 push    ebx
  701. ;--NOT USED!!--                 mov     ebx, 15
  702. ;--NOT USED!!--                 sub     bl, ah
  703. ;--NOT USED!!--                 shl     ebx, 8
  704. ;--NOT USED!!--                 movzx   ecx, BaseColor
  705. ;--NOT USED!!--                 add     ebx, ecx
  706. ;--NOT USED!!--                 add     ebx, offset _gr_fade_table
  707. ;--NOT USED!!--                 mov     ah, [ebx]
  708. ;--NOT USED!!--                 pop     ebx
  709. ;--NOT USED!!--                 pop     ecx
  710. ;--NOT USED!!-- 
  711. ;--NOT USED!!--                 mov     [esi],ah ;DrawPixel(X, Y, BaseColor + Weighting);
  712. ;--NOT USED!!-- 
  713. ;--NOT USED!!--                 mov     ah,dh   ;msb of ErrorAcc
  714. ;--NOT USED!!--                 shr     ah,cl   ;Weighting = ErrorAcc >> IntensityShift;
  715. ;--NOT USED!!--                 xor     ah,ch   ;Weighting ^ WeightingComplementMask
  716. ;--NOT USED!!--                 ;add     ah,al   ;BaseColor + (Weighting ^ WeightingComplementMask)
  717. ;--NOT USED!!-- 
  718. ;--NOT USED!!--                 ; Make ah =   _gr_fade_table + BaseColor+(15-ah)*256
  719. ;--NOT USED!!--                 push    ecx
  720. ;--NOT USED!!--                 push    ebx
  721. ;--NOT USED!!--                 mov     ebx, 15
  722. ;--NOT USED!!--                 sub     bl, 0
  723. ;--NOT USED!!--                 shl     ebx, 8
  724. ;--NOT USED!!--                 movzx   ecx, BaseColor
  725. ;--NOT USED!!--                 add     ebx, ecx
  726. ;--NOT USED!!--                 add     ebx, offset _gr_fade_table
  727. ;--NOT USED!!--                 mov     ah, [ebx]
  728. ;--NOT USED!!--                 pop     ebx
  729. ;--NOT USED!!--                 pop     ecx
  730. ;--NOT USED!!-- 
  731. ;--NOT USED!!-- 
  732. ;--NOT USED!!--                 mov     [esi+ebx],ah ;DrawPixel(X+XDir, Y,
  733. ;--NOT USED!!--                                                 ; BaseColor + (Weighting ^ WeightingComplementMask));
  734. ;--NOT USED!!--                 dec     di  ;--DeltaY
  735. ;--NOT USED!!--                 jnz     YMajorLoop
  736. ;--NOT USED!!--                 jmp     DoneAA    ;we're done with this line
  737. ;--NOT USED!!-- 
  738. ;--NOT USED!!-- ; It's an X-major line.
  739. ;--NOT USED!!-- XMajorAA:
  740. ;--NOT USED!!-- ; Calculate the 16-bit fixed-point fractional part of a pixel that Y advances
  741. ;--NOT USED!!-- ; each time X advances 1 pixel, truncating the result to avoid overrunning
  742. ;--NOT USED!!-- ; the endpoint along the X axis.
  743. ;--NOT USED!!--                 sub     eax,eax       ;make DeltaY 16.16 fixed-point value in DX:AX
  744. ;--NOT USED!!--                 div     ecx      ;AX = (DeltaY << 16) / Deltax. Won't overflow
  745. ;--NOT USED!!--                                                                 ; because DeltaY < DeltaX
  746. ;--NOT USED!!--                 mov     edi,ecx       ;DI = DeltaX (loop count)
  747. ;--NOT USED!!--                 sub     esi,_gr_var_bwidth ;back up the start X by 1, as
  748. ;--NOT USED!!--                                                                 ; explained below
  749. ;--NOT USED!!--                 mov     edx,-1       ;initialize the line error accumulator to -1,
  750. ;--NOT USED!!--                                                                 ; so that it will turn over immediately and
  751. ;--NOT USED!!--                                                                 ; advance Y to the start Y. This is necessary
  752. ;--NOT USED!!--                                                                 ; properly to bias error sums of 0 to mean
  753. ;--NOT USED!!--                                                                 ; "advance next time" rather than "advance
  754. ;--NOT USED!!--                                                                 ; this time," so that the final error sum can
  755. ;--NOT USED!!--                                                                 ; never cause drawing to overrun the final Y
  756. ;--NOT USED!!--                                                                 ; coordinate (works in conjunction with
  757. ;--NOT USED!!--                                                                 ; truncating ErrorAdj, to make sure Y can't
  758. ;--NOT USED!!--                                                                 ; overrun)
  759. ;--NOT USED!!--                 mov     cl,8            ;CL = # of bits by which to shift
  760. ;--NOT USED!!--                 sub     cl,IntensityBits   ; ErrorAcc to get intensity level (8
  761. ;--NOT USED!!--                                                                                 ; instead of 16 because we work only
  762. ;--NOT USED!!--                                                                                 ; with the high byte of ErrorAcc)
  763. ;--NOT USED!!--                 mov     ch,NumLevels ;mask used to flip all bits in an
  764. ;--NOT USED!!--                 dec     ch             ; intensity weighting, producing
  765. ;--NOT USED!!--                                                                                    ; result (1 - intensity weighting)
  766. ;--NOT USED!!-- 
  767. ;--NOT USED!!--                 mov     ebp, eax
  768. ;--NOT USED!!--                 mov     al, BaseColor
  769. ;--NOT USED!!-- 
  770. ;--NOT USED!!-- ; Draw all remaining pixels.
  771. ;--NOT USED!!-- XMajorLoop:
  772. ;--NOT USED!!--                 add     edx,ebp           ;calculate error for next pixel
  773. ;--NOT USED!!--                         jnc     NoYAdvance              ;not time to step in Y yet
  774. ;--NOT USED!!--                                                                                                                                                                 ;the error accumulator turned over,
  775. ;--NOT USED!!--                                                                                                                                                                 ; so advance the Y coord
  776. ;--NOT USED!!--                                 add     esi,_gr_var_bwidth ;advance Y
  777. ;--NOT USED!!-- NoYAdvance:
  778. ;--NOT USED!!--                                 add     esi,ebx       ;X-major, so add XDir to the pixel pointer
  779. ;--NOT USED!!-- 
  780. ;--NOT USED!!-- ; The IntensityBits most significant bits of ErrorAcc give us the intensity
  781. ;--NOT USED!!-- ; weighting for this pixel, and the complement of the weighting for the
  782. ;--NOT USED!!-- ; paired pixel.
  783. ;--NOT USED!!--                 mov     ah,dh   ;msb of ErrorAcc
  784. ;--NOT USED!!--                 shr     ah,cl   ;Weighting = ErrorAcc >> IntensityShift;
  785. ;--NOT USED!!--                 ;add     ah,al   ;BaseColor + Weighting
  786. ;--NOT USED!!-- 
  787. ;--NOT USED!!--                 ; Make ah =   _gr_fade_table + BaseColor+(15-ah)*256
  788. ;--NOT USED!!--                 push    ecx
  789. ;--NOT USED!!--                 push    ebx
  790. ;--NOT USED!!--                 mov     ebx, 15
  791. ;--NOT USED!!--                 sub     bl, ah
  792. ;--NOT USED!!--                 shl     ebx, 8
  793. ;--NOT USED!!--                 movzx   ecx, BaseColor
  794. ;--NOT USED!!--                 add     ebx, ecx
  795. ;--NOT USED!!--                 add     ebx, offset _gr_fade_table
  796. ;--NOT USED!!--                 mov     ah, [ebx]
  797. ;--NOT USED!!--                 pop     ebx
  798. ;--NOT USED!!--                 pop     ecx
  799. ;--NOT USED!!-- 
  800. ;--NOT USED!!-- 
  801. ;--NOT USED!!--                 mov     [esi],ah ;DrawPixel(X, Y, BaseColor + Weighting);
  802. ;--NOT USED!!--                 mov     ah,dh   ;msb of ErrorAcc
  803. ;--NOT USED!!--                 shr     ah,cl   ;Weighting = ErrorAcc >> IntensityShift;
  804. ;--NOT USED!!--                 xor     ah,ch   ;Weighting ^ WeightingComplementMask
  805. ;--NOT USED!!--                 ;add     ah,al   ;BaseColor + (Weighting ^ WeightingComplementMask)
  806. ;--NOT USED!!--                 add     esi, _gr_var_bwidth
  807. ;--NOT USED!!-- 
  808. ;--NOT USED!!--                 ; Make ah =   _gr_fade_table + BaseColor+(15-ah)*256
  809. ;--NOT USED!!--                 push    ecx
  810. ;--NOT USED!!--                 push    ebx
  811. ;--NOT USED!!--                 mov     ebx, 15
  812. ;--NOT USED!!--                 sub     bl, ah
  813. ;--NOT USED!!--                 shl     ebx, 8
  814. ;--NOT USED!!--                 movzx   ecx, BaseColor
  815. ;--NOT USED!!--                 add     ebx, ecx
  816. ;--NOT USED!!--                 add     ebx, offset _gr_fade_table
  817. ;--NOT USED!!--                 mov     ah, [ebx]
  818. ;--NOT USED!!--                 pop     ebx
  819. ;--NOT USED!!--                 pop     ecx
  820. ;--NOT USED!!-- 
  821. ;--NOT USED!!-- 
  822. ;--NOT USED!!--                 mov     [esi],ah    ;DrawPixel(X, Y+SCREEN_WIDTH_IN_BYTES,
  823. ;--NOT USED!!--                                                 ; BaseColor + (Weighting ^ WeightingComplementMask));
  824. ;--NOT USED!!--                 sub     esi, _gr_var_bwidth
  825. ;--NOT USED!!--                 dec     edi  ;--DeltaX
  826. ;--NOT USED!!--                 jnz     XMajorLoop
  827. ;--NOT USED!!-- 
  828. ;--NOT USED!!-- DoneAA:               ;we're done with this line
  829. ;--NOT USED!!--                 pop edi  ;restore C's register variables
  830. ;--NOT USED!!--                 pop esi
  831. ;--NOT USED!!--                 pop ebp  ;restore caller's stack frame
  832. ;--NOT USED!!--                 ret     ;done
  833.  
  834.  
  835.  
  836. _TEXT   ENDS
  837.  
  838.  
  839.         END
  840.