home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 11 / CD_ASCQ_11_0294.iso / maj / 666 / xfill.asm < prev    next >
Assembly Source File  |  1993-10-03  |  11KB  |  534 lines

  1. ;-----------------------------------------------------------------------
  2. ; MODULE XFILL
  3. ;
  4. ; Point functions all MODE X 256 Color resolutions
  5. ;
  6. ; Compile with Tasm.
  7. ; C callable.
  8. ;
  9. ;
  10. ; ****** XLIB - Mode X graphics library                ****************
  11. ; ******                                               ****************
  12. ; ****** Written By Themie Gouthas                     ****************
  13. ;
  14. ; egg@dstos3.dsto.gov.au
  15. ; teg@bart.dsto.gov.au
  16. ;-----------------------------------------------------------------------
  17.  
  18. COMMENT $
  19.  
  20.   This code is my interpretation of a simple "C" flood filling algorithm
  21.   titled:
  22.  
  23.   * A Seed Fill Algorithm
  24.   * by Paul Heckbert
  25.   * from "Graphics Gems", Academic Press, 1990
  26.  
  27.   The original C source is readily available at numerous internet archive
  28.   sites.
  29.  
  30.   Its been modified and optimized for tweaked 13h modes (Mode X derrivatives).
  31.   The most fundamental change is that it fills a column at a time rather
  32.   than a row at a time to minimize the number of plane setting "out"s.
  33.   And of course the border fill variant was a logical and useful further
  34.   modification.
  35.  
  36.   Both functions return the number of pixels filled..
  37.  
  38.   WARNING: These fill functions make heavy use of the stack and no stack
  39.     checking is performed, so caution is advised.
  40.  
  41. $
  42.  
  43.  
  44. include xlib.inc
  45. include xfill.inc
  46.  
  47.     .code
  48.  
  49. _x_flood_fill  proc
  50.     ARG X:word,Y:word,PgOfs:word,Color:word
  51.     LOCAL len:word,y1:word,y2:word,deltax:word,floodval:word,\
  52.           stackptr:word,FillCount:word=STK
  53.     push bp
  54.     mov  bp,sp
  55.     sub  sp,STK
  56.     mov  [FillCount],0
  57.     push di si
  58.     mov  si,[Y]
  59.     mov  ax,[_ScrnLogicalByteWidth]
  60.     mul  si                   ;offset of pixel's scan line in page
  61.     mov  di,[X]
  62.     mov  bx,di
  63.     shr  di,2                 ;X/4 = offset of pixel in scan line
  64.     add  di,ax                ;offset of pixel in page
  65.     add  di,[PgOfs]           ;offset of pixel in display memory
  66.     mov  ax,SCREEN_SEG
  67.     mov  es,ax                ;point ES:DI to the pixel's address
  68.  
  69.     ;---- Select read plane ------
  70.  
  71.     mov  ah,bl
  72.     and  ah,011b              ;AH = pixel's plane
  73.     mov  al,READ_MAP          ;AL = index in GC of the Read Map reg
  74.     mov  dx,GC_INDEX          ;set the Read Map to read the pixel's
  75.     out  dx,ax                ; plane
  76.  
  77.     mov  al,es:[di]           ;read the pixel's color
  78.     cmp  al,byte ptr Color    ;Is dest pixel the same color as the flood?
  79.     je   @@Done2              ; if it is abort.
  80.  
  81.     mov  cx,_LeftClip         ; Is the dest. pixel out of the clipping window?
  82.     sal  cx,2                 ;  if not abort.
  83.     cmp  bx,cx
  84.     jl   @@Done2
  85.  
  86.     mov  cx,_RightClip
  87.     sal  cx,2
  88.     cmp  bx,cx
  89.     jg   @@Done2
  90.  
  91.     mov  floodval,ax           ; store the color to flood
  92.  
  93.     ;-- Push fill segment ---
  94.  
  95.     push bx         ; X
  96.     push si         ; Y
  97.     push si         ; Y
  98.     mov  cx,1       ; deltaX  (either 1 or -1 indicating direction)
  99.     push cx
  100.     mov  stackptr,1
  101.  
  102.     mov  deltax,-1  ; Initialize first column scan
  103.     mov  y1,si      ;   then bypass some of the preliminary crap in
  104.     mov  y2,si      ;   the main fill loop
  105.     jmp  short @@entry
  106.  
  107. @@Done2:mov  ax,[FillCount]
  108.     pop  si di
  109.     mov  sp,bp
  110.     pop  bp
  111.     ret
  112.  
  113. @@NextScanCol:
  114.     dec  stackptr
  115.     js   @@Done2
  116.  
  117. @@WhileLoop:
  118.     pop  cx           ; get fill segment from stack
  119.     mov  deltax,cx    ; ie deltaX, Y1, Y2, X
  120.     pop  ax
  121.     mov  y2,ax
  122.     pop  si
  123.     mov  y1,si
  124.     pop  bx
  125.  
  126.     sub  ax,si           ; Acculmulate number of filled pixels
  127.     jns  @@PositiveY
  128.     neg  ax
  129. @@PositiveY:
  130.     add  FillCount,ax
  131.  
  132.  
  133.     add  bx,cx          ; move to new column according to deltaX
  134.  
  135.     mov  ax,bx          ; Make sure the column is within the clipping
  136.     sar  ax,2           ; rectangle
  137.     cmp  ax,_LeftClip
  138.     jl   @@NextScanCol
  139.  
  140.     cmp  ax,_RightClip
  141.     jg   @@NextScanCol
  142.  
  143.  
  144.     ;---- Select read plane ------
  145.  
  146.     mov  ah,bl
  147.     and  ah,011b              ;AH = pixel's plane
  148.     mov  al,READ_MAP          ;AL = index in GC of the Read Map reg
  149.     mov  dx,GC_INDEX          ;set the Read Map to read the pixel's
  150.     out  dx,ax                ; plane
  151.  
  152. @@entry:
  153.  
  154.     ;---- Select write plane ------
  155.  
  156.     mov  cl,bl
  157.     and  cl,011b              ;CL = pixel's plane
  158.     mov  ax,0100h + MAP_MASK  ;AL = index in SC of Map Mask reg
  159.     shl  ah,cl                ;set only the bit for the pixel's
  160.                   ; plane to 1
  161.     mov  dx,SC_INDEX          ;set the Map Mask to enable only the
  162.     out  dx,ax                ; pixel's plane
  163.  
  164.     mov  ax,_ScrnLogicalByteWidth     ; store logical width in CX
  165.     mov  cx,ax                        ; get offset of scan row
  166.     mul  si                           ; set ES:DI ->
  167.     mov  di,bx                        ; address of pixel at x,y1
  168.     shr  di,2
  169.     add  di,ax
  170.     add  di,PgOfs          ;ES:DI->first pixel of column segment to fill
  171.     mov  dx,di             ; save y1 offset for after upward fill
  172.  
  173.     mov  al,byte ptr Color
  174.     mov  ah,byte ptr floodval
  175.  
  176. @@FillColUpward:
  177.     cmp  si,_TopClip           ; Dont fill beyond clip boundaries
  178.     jl   @@UpwardFillDone
  179.  
  180.     cmp  es:[di],ah            ; if flood pixel color then replace
  181.     jne  @@UpwardFillDone      ; with new color otherwise column is done
  182.  
  183.     mov  es:[di],al
  184.     sub  di,cx
  185.     dec  si
  186.     jmp  short @@FillColUpward
  187.  
  188. @@UpwardFillDone:
  189.     cmp  si,y1
  190.     jge  @@Skip
  191.  
  192.     inc  si
  193.     mov  len,si
  194.  
  195.     cmp  si,y1
  196.     jge  @@AtColumnTop
  197.  
  198.     push bx     ;  queue an upward leak check
  199.     push si
  200.     mov  ax,y1
  201.     dec  ax
  202.     push ax
  203.     mov  ax,deltax
  204.     neg  ax
  205.     push ax
  206.     inc  stackptr
  207.  
  208. @@AtColumnTop:
  209.     mov  si,y1
  210.     mov  di,dx
  211.     add  di,cx
  212.     inc  si
  213.  
  214.  
  215. @@ColumnLoop:
  216.     mov  ah,byte ptr floodval
  217.     mov  al,byte ptr Color
  218.  
  219. @@DownwardFill:
  220.     cmp  si,_BottomClip
  221.     jg   @@DownwardFillDone
  222.     cmp  es:[di],ah
  223.     jne  @@DownwardFillDone
  224.     mov  es:[di],al
  225.     add  di,cx
  226.     inc  si
  227.     jmp  short @@DownwardFill
  228.  
  229. @@DownwardFillDone:
  230.  
  231.     push bx      ; queue an upward leak check
  232.     mov  ax,len
  233.     push ax
  234.     mov  ax,si
  235.     dec  ax
  236.     push ax
  237.     mov  ax,deltax
  238.     push ax
  239.     inc  stackptr
  240.  
  241.     mov  ax,y2
  242.     inc  ax
  243.     cmp  si,ax
  244.     jle  @@Skip
  245.  
  246.     push bx       ;  queue a downward leak check
  247.     push ax
  248.     mov  ax,si
  249.     dec  ax
  250.     push ax
  251.     mov  ax,deltax
  252.     neg  ax
  253.     push ax
  254.     inc  stackptr
  255.  
  256. @@Skip:
  257.     mov  ah,byte ptr floodval
  258.     mov  dx,y2
  259.  
  260. @@Backtrack:
  261.     add  di,cx
  262.     inc  si
  263.     cmp  si,dx
  264.     jg   @@BacktrackDone
  265.  
  266.     cmp  byte ptr es:[di],ah
  267.     jne  @@Backtrack
  268.  
  269. @@BacktrackDone:
  270.     mov  len,si
  271.     cmp  si,dx
  272.     jle  @@ColumnLoop
  273.  
  274.     dec  stackptr
  275.     js   @@Done
  276.     jmp  @@WhileLoop
  277. @@Done:
  278.     mov  ax,[FillCount]
  279.     pop  si di
  280.     mov  sp,bp
  281.     pop  bp
  282.     ret
  283. _x_flood_fill   endp
  284.  
  285.  
  286. _x_boundary_fill  proc
  287.     ARG X:word,Y:word,PgOfs:word,BoundaryColor:word,Color:word
  288.     LOCAL len:word,y1:word,y2:word,deltax:word,y1_offs:word,\
  289.           stackptr:word,FillCount:word=STK
  290.     push bp
  291.     mov  bp,sp
  292.     sub  sp,STK
  293.     mov  [FillCount],0
  294.     push di si
  295.     mov  si,[Y]
  296.     mov  ax,[_ScrnLogicalByteWidth]
  297.     mul  si                  ;offset of pixel's scan line in page
  298.     mov  di,[X]
  299.     mov  bx,di
  300.     shr  di,2                 ;X/4 = offset of pixel in scan line
  301.     add  di,ax                ;offset of pixel in page
  302.     add  di,[PgOfs]           ;offset of pixel in display memory
  303.     mov  ax,SCREEN_SEG
  304.     mov  es,ax                ;point ES:DI to the pixel's address
  305.  
  306.     ;---- Select read plane ------
  307.  
  308.     mov  ah,bl
  309.     and  ah,011b              ;AH = pixel's plane
  310.     mov  al,READ_MAP          ;AL = index in GC of the Read Map reg
  311.     mov  dx,GC_INDEX          ;set the Read Map to read the pixel's
  312.     out  dx,ax                ; plane
  313.  
  314.     mov  al,es:[di]           ;read the pixel's color
  315.     cmp  al,byte ptr Color    ;Is dest pixel the same color as the flood?
  316.     je   @@Done2
  317.  
  318.     cmp  al,byte ptr BoundaryColor ;Is dest pixel the same color
  319.     je   @@Done2                   ; as the boundary color?
  320.  
  321.  
  322.     mov  cx,_LeftClip         ; Is the dest. pixel out of the clipping window?
  323.     sal  cx,2
  324.     cmp  bx,cx
  325.     jl   @@Done2
  326.  
  327.     mov  cx,_RightClip
  328.     sal  cx,2
  329.     cmp  bx,cx
  330.     jg   @@Done2
  331.  
  332.     push bx      ; X
  333.     push si      ; Y
  334.     push si      ; Y
  335.     mov  cx,1    ; DX
  336.     push cx
  337.     mov  stackptr,1
  338.     mov  al,byte ptr BoundaryColor
  339.     mov  byte ptr [Color+1],al
  340.  
  341.     mov  deltax,-1
  342.     mov  y1,si
  343.     mov  y2,si
  344.     jmp  short @@entry
  345.  
  346. @@Done2:mov  ax,[FillCount]
  347.     pop  si di
  348.     mov  sp,bp
  349.     pop  bp
  350.     ret
  351.  
  352. @@NextScanCol:
  353.     dec  stackptr
  354.     js   @@Done2
  355.  
  356. @@WhileLoop:
  357.     pop  cx
  358.     mov  deltax,cx
  359.     pop  ax
  360.     mov  y2,ax
  361.     pop  si
  362.     mov  y1,si
  363.     pop  bx
  364.     add  bx,cx   ; bx = X
  365.  
  366.     sub  ax,si           ; Acculmulate number of filled pixels
  367.     jns  @@PositiveY
  368.     neg  ax
  369. @@PositiveY:
  370.     add  FillCount,ax
  371.  
  372.  
  373.  
  374.     mov  ax,bx          ; Make sure the column is within the clipping
  375.     sar  ax,2           ; rectangle
  376.     cmp  ax,_LeftClip
  377.     jl   @@NextScanCol
  378.     cmp  ax,_RightClip
  379.     jg   @@NextScanCol
  380.  
  381.  
  382.     ;---- Select read plane ------
  383.  
  384.     mov  ah,bl
  385.     and  ah,011b              ;AH = pixel's plane
  386.     mov  al,READ_MAP          ;AL = index in GC of the Read Map reg
  387.     mov  dx,GC_INDEX          ;set the Read Map to read the pixel's
  388.     out  dx,ax                ; plane
  389.  
  390. @@entry:
  391.  
  392.     ;---- Select write plane ------
  393.  
  394.     mov  cl,bl
  395.     and  cl,011b              ;CL = pixel's plane
  396.     mov  ax,0100h + MAP_MASK  ;AL = index in SC of Map Mask reg
  397.     shl  ah,cl                ;set only the bit for the pixel's
  398.                   ; plane to 1
  399.     mov  dx,SC_INDEX          ;set the Map Mask to enable only the
  400.     out  dx,ax                ; pixel's plane
  401.  
  402.     mov  ax,_ScrnLogicalByteWidth     ; store logical width in CX
  403.     mov  cx,ax                        ; get offset of scan row
  404.     mul  si                           ; set ES:DI ->
  405.     mov  di,bx                        ; address of pixel at x,y1
  406.     shr  di,2
  407.     add  di,ax
  408.     add  di,PgOfs
  409.     mov  y1_offs,di                   ; save y1 offset for after upward fill
  410.  
  411.     mov   ax,Color                    ; al = Color ah = BoundaryColor
  412.  
  413. @@FillColUpward:
  414.     cmp  si,_TopClip                  ; Dont fill beyond clip boundaries
  415.     jl   @@UpwardFillDone
  416.  
  417.     mov  dl,es:[di]
  418.     cmp  dl,ah
  419.     je   @@UpwardFillDone
  420.  
  421.     cmp  dl,al
  422.     je   @@UpwardFillDone
  423.  
  424.     mov  es:[di],al
  425.     sub  di,cx
  426.     dec  si
  427.     jmp  short @@FillColUpward
  428.  
  429. @@UpwardFillDone:
  430.     cmp  si,y1
  431.     jge  @@Skip
  432.  
  433.     inc  si
  434.     mov  len,si
  435.  
  436.     cmp  si,y1
  437.     jge  @@AtColumnTop
  438.  
  439.     push bx     ;  queue an upward leak check
  440.     push si
  441.     mov  ax,y1
  442.     dec  ax
  443.     push ax
  444.     mov  ax,deltax
  445.     neg  ax
  446.     push ax
  447.     inc  stackptr
  448.  
  449. @@AtColumnTop:
  450.     mov  si,y1
  451.     mov  di,y1_offs
  452.     add  di,cx
  453.     inc  si
  454.  
  455.  
  456. @@ColumnLoop:
  457.     mov   ax,Color           ; al = Color ah = BoundaryColor
  458.  
  459. @@DownwardFill:
  460.     cmp  si,_BottomClip
  461.     jg   @@DownwardFillDone
  462.  
  463.     cmp  es:[di],ah
  464.     je   @@DownwardFillDone
  465.  
  466.     cmp  es:[di],al
  467.     je   @@DownwardFillDone
  468.  
  469.     mov  es:[di],al
  470.     add  di,cx
  471.     inc  si
  472.     jmp  short @@DownwardFill
  473.  
  474. @@DownwardFillDone:
  475.  
  476.     push bx      ; queue an upward leak check
  477.     mov  ax,len
  478.     push ax
  479.     mov  ax,si
  480.     dec  ax
  481.     push ax
  482.     mov  ax,deltax
  483.     push ax
  484.     inc  stackptr
  485.  
  486.     mov  ax,y2
  487.     inc  ax
  488.     cmp  si,ax
  489.     jle  @@Skip
  490.  
  491.     push bx       ;  queue a downward leak check
  492.     push ax
  493.     mov  ax,si
  494.     dec  ax
  495.     push ax
  496.     mov  ax,deltax
  497.     neg  ax
  498.     push ax
  499.     inc  stackptr
  500.  
  501. @@Skip:
  502.     mov  ax,Color                ; al = Color ah = BoundaryColor
  503.  
  504. @@Backtrack:
  505.     add  di,cx
  506.     inc  si
  507.     cmp  si,y2
  508.     jg   @@BacktrackDone
  509.  
  510.     mov  dl,byte ptr es:[di]
  511.     cmp  dl,al
  512.     je   @@Backtrack
  513.  
  514.     cmp  dl,ah
  515.     je   @@Backtrack
  516.  
  517. @@BacktrackDone:
  518.     mov  len,si
  519.     cmp  si,y2
  520.     jle  @@ColumnLoop
  521.  
  522.     dec  stackptr
  523.     js   @@Done
  524.     jmp  @@WhileLoop
  525. @@Done:
  526.     mov  ax,[FillCount]
  527.     pop  si di
  528.     mov  sp,bp
  529.     pop  bp
  530.     ret
  531. _x_boundary_fill   endp
  532.  
  533. end
  534.