CPC-POWER : CPC-SOFTS - CPCArchives 
Options de Recherche :
 
 
 

ARTICLES

67 / 74

GAC Fast Line Fill

By Bruce ABBOTT (bruce.abbott@xtra.co.nz)

Information on cpcwiki

 

This patch speeds up GAC's area fill routine. The original code examined each pixel in the line to get the left and right edges of the area to be filled,  then drew a line between them using the ROM function SCR HORIZONTAL.

My code fills in the line directly _while_ examining the pixels, resulting  in a HUGE speed up! (up to 8x faster). Most pictures draw 3~5 times faster  than before.

 

Fills one horizontal line with pattern (stops when it hits another color)

entry; HL = y, DE = x (coordinates to start filling from)
exit;  HL = y, Carry Set (and no line drawn) if start pixel not paper color 


changes:


2013-11-4  V1.0 Initial release, created with WinAPE 2.0 Alpha 18

2013-11-14 V1.1 Avoids filling top and bottom lines of picture frame. Repairs vertical picture frame lines at end of fill.

2013-11-15 V1.2 Constrained to picture area, no need to repair frame!

2013-11-16 V1.2b Reduced code size by 3 bytes.

 

VERSION 1.1

    ORG #2500          ; patch installs over original code at &2500
    PUSH DE            ; save x
    PUSH HL            ; save y
    LD A,L
    CP #46             ; abort if top of picture (y=70)  
    JR Z,abort
    CP #C7             ; abort if bottom of picture (y=199)
    JR Z,abort
    CALL #BC1D         ; SCR DOT POSITION -> addr=HL, numbits-1=B, mask=C
    LD A,(#4029)
    XOR (HL)           ; color at x,y same as paper color?
    AND C
    JR Z,fill_line     ; yes, fill the line
.abort:
    SCF                ; no, return with carry flag set = hit boundary        
    POP HL             ; restore y
    POP DE             ; restore x
    RET
.fill_line:
    POP DE             ; get y coord off stack
    PUSH DE            ; put y coord back on stack       
    LD A,(#4026)       ; get fill pattern for odd lines
    BIT 0,E            ; is it an odd line?
    JR NZ,odd
    LD A,(#4027)       ; no, get fill pattern for even lines
.odd:
    LD D,A             ; D = fill pattern
    LD A,(#4029)
    LD E,A             ; E = paper color
    PUSH HL            ; save pixel address
    PUSH BC            ; save mask
.fill_left:    
    LD A,E             ; A = paper color
.left_pixel:
    XOR (HL)           ; compare pixel color to paper color
    AND C            
    JR NZ,done_left    ; stop going left if hit edge of fill area
    LD A,D             ; A = fill pattern
    XOR (HL)
    AND C              ; mask off other pixels
    XOR (HL)
    LD (HL),A          ; set pixel to fill pattern color
    RLC C              ; rotate mask to select next pixel
    JR NC,fill_left    ; if not end of byte then do next pixel
    LD A,E             ; A = paper color
.left_byte:    
    DEC HL             ; screen address - 1
    CP (HL)            ; test 4 pixels at once
    JR NZ,left_pixel   ; if not all paper color then test single pixels
    LD (HL),D          ; set byte to fill pattern
    JR left_byte       ; do next byte
.done_left:
    POP BC             ; back to start position (HL=address, C=mask)
    POP HL
    PUSH HL            ; save pixel address
    JR next_right      ; start filling towards the right
.fill_right:
    LD A,E             ; A = paper color
.right_pixel:
    XOR (HL)           ; compare pixel color to paper color
    AND C
    JR NZ,repairframe  ; stop going right if hit edge of fill area
    LD A,D             ; A = fill pattern
    XOR (HL)
    AND C              ; mask off other pixels
    XOR (HL)
    LD (HL),A          ; set pixel to fill pattern color
.next_right:
    RRC C              ; rotate mask to select next pixel
    JR NC,fill_right   ; if not end of byte then do next pixel
    LD A,E             ; A = paper color
.right_byte:
    INC HL             ; screen address + 1
    CP (HL)            ; test 4 pixels at once
    JR NZ,right_pixel  ; if not all paper color then test single pixels
    LD (HL),D          ; set byte to fill pattern
    JR right_byte      ; do next byte
.fill_end:

; ----------- don't redraw the picture frame after every fill! ------------
;
    ORG #2592          ; patch installs over original code at &2592         
.drawframe:
    RET
.df_end:

;--- Repair left and right picture frame where fill may have touched it ---
;
    ORG #25CB          ; patch installs over original code at &25CB
.repairframe:
    POP HL             ; restore pixel address
    POP DE             ; restore y
    POP BC             ; restore x
    SRL B
    RR  C
    SRL B
    RR  C              ; BC / 4 = byte position of pixel on line
    LD  A,C
    SUB #07            ; - left frame byte position  
    LD  C,A
    SBC HL,BC          ; HL = address of left frame byte
    LD  (HL),#10       ; set rightmost pixel in byte to frame color
    LD  C,#41
    ADD HL,BC          ; HL = address of right frame byte    
    LD  (HL),#80       ; set leftmost pixel in byte to frame color
    LD  H,D
    LD  L,E            ; HL = y
    RET                ; return with Carry Clear = line filled OK
.rp_end:

 

VERSION 1.2b

    ORG #1E80       ; patch installs over original code at &1E80 
.convert:
        LD A,D
    SRL A           
    LD A,E           ; A = x/4
    RRA           
        SRL A
    SUB #07           ; -7 = number of bytes to left edge of picture
    PUSH AF           ; save numbytes
    CALL #BC1D       ; SCR DOT POSITION -> addr=HL, numbits-1=B, mask=C
    POP AF
    LD B,A           ; b = number of bytes to left edge
    RET
.con_end:
    if #1e90-$ AND #8000
    ORG too_much_code!
    endif

    ORG #2500       ; patch installs over original code at &2500
.fill:
    PUSH HL           ; save y
    LD A,L
    CP #46           ; abort if at bottom of picture (y=70)  
    JR Z,abort
    CP #C7           ; abort if at top of picture (y=199)
    JR Z,abort
    PUSH HL           ; save y
    CALL convert       ; convert (x,y) to scr addr, numbytes, mask
    POP DE           ; DE = y
    LD A,(#4029)
    XOR (HL)       ; color at (x,y) same as paper color?
    AND C
    JR Z,fill_line       ; yes, fill the line
.abort:
    SCF           ; no, return with carry flag set = hit boundary        
    POP HL           ; restore y
    RET

.fill_line:
        BIT 0,E           ; odd line?
    LD DE,(#4026)      ; D = even fill pattern, E = odd fill pattern  
        JR Z,even        
    LD D,E           ; yes, D = odd fill pattern
.even:    LD A,(#4029)
    LD E,A           ; E = paper color
    PUSH HL           ; save pixel address
    PUSH BC           ; save numbytes, mask
.fill_left:    
    LD A,E           ; A = paper color
.left_pixel:
    XOR (HL)       ; compare pixel color to paper color
    AND C            
    JR NZ,done_left       ; stop going left if hit edge of fill area
    LD A,D           ; A = fill pattern
    XOR (HL)
    AND C           ; mask off other pixels
        XOR (HL)
    LD (HL),A       ; set pixel to fill pattern color
    RLC C           ; rotate mask to select next pixel
    JR NC,fill_left    ; if not end of byte then do next pixel
    LD A,E           ; A = paper color
    JR byte_left       
.left_byte:    
    DEC HL           ; screen address - 1
    CP (HL)           ; test 4 pixels at once
    JR NZ,left_pixel   ; if not all paper color then test single pixels
    LD (HL),D       ; set byte to fill pattern
.byte_left:
    DJNZ left_byte       ; keep going until left edge reached
    
.done_left:           ; back to start position
    POP BC           ; B=bytes to left edge, C=mask,
    POP HL           ; HL=address
    LD A,#41
    SUB B           ; B = number of bytes to right edge of picture
    LD B,A
    JR next_right       ; start filling towards the right
.fill_right:
    LD A,E           ; A = paper color
.right_pixel:
    XOR (HL)       ; compare pixel color to paper color
    AND C
    JR NZ,fill_done    ; stop going right if hit edge of fill area
    LD A,D           ; A = fill pattern
    XOR (HL)
    AND C           ; mask off other pixels
        XOR (HL)
    LD (HL),A       ; set pixel to fill pattern color
.next_right:
    RRC C           ; rotate mask to select next pixel
    JR NC,fill_right   ; if not end of byte then do next pixel
    LD A,E           ; A = paper color
    JR   byte_right   
.right_byte:
    INC HL           ; screen address + 1
    CP (HL)           ; test 4 pixels at once
    JR NZ,right_pixel  ; if not all paper color then test single pixels
    LD (HL),D       ; set byte to fill pattern
.byte_right:
    DJNZ right_byte       ; keep going until right edge reached
.fill_done:
    POP HL           ; restore y
    AND A           ; Carry clear = line filled
    RET
.fill_end:
    if #2564-$ AND #8000
    ORG  too_much_code!
    endif

; ----------- don't redraw the picture frame after every fill! ------------
;
    ORG #2592       ; patch installs over original code at &2592         
.drawframe:
    RET
.drawframe_end:


Les "GAC Fast Line Fill" patchs présents dans notre BDD :

FICHIERS : 26
C
Cricket Crazy (UK) (1988) [GAC Fast Line Fill].zip
D
Don Quijote (S) (1987) [GAC Fast Line Fill].zip
F
Football frenzy (UK) (1987) [GAC Fast Line Fill].zip
For Gold Or Glory (UK) (1989) [GAC Fast Line Fill].zip
G
GAC Fast Fill Patch V1.2b (UK) (2013) (Version Basic 1.1) [GAC Fast Line Fill] [UTILITAIRE].zip
H
Haunted House (UK) (1987) [GAC Fast Line Fill].zip
K
Ke Rulen Los Petas (S) (1989) [GAC Fast Line Fill].zip
L
La Corona (S) (1988) [GAC Fast Line Fill].zip
La Guerra De Las Vajillas (S) (1988) [GAC Fast Line Fill].zip
Legend (S) (1990) [GAC Fast Line Fill].zip
Los Pajaros De Bangkog (S) (1988) [GAC Fast Line Fill].zip
M
Mantis 1 (S) (1990) [GAC Fast Line Fill].zip
Mantis 2 (S) (1990) [GAC Fast Line Fill].zip
Megacorp (S) (1987) [GAC Fast Line Fill].zip
Mountains Of Ket (UK) (1987) [GAC Fast Line Fill].zip
N
Nocturne (UK) (1986) [GAC Fast Line Fill].zip
Nova! (UK) (1987) [GAC Fast Line Fill].zip
S
Sharpe's Deeds (UK) (1987) [GAC Fast Line Fill].zip
T
The Beer Hunter (UK) (1986) [GAC Fast Line Fill].zip
The Black Fountain (UK) (1987) [GAC Fast Line Fill].zip
The Legend Of Apache Gold (UK) (1987) [GAC Fast Line Fill].zip
The Multi-Realm Cave Capers (UK) (1989) [GAC Fast Line Fill].zip
The Necris-Dome (UK) (1986) [GAC Fast Line Fill].zip
Top Secret (UK) (1987) [Incentive] [GAC Fast Line Fill].zip
W
Winter Wonderland (UK) (1987) [GAC Fast Line Fill].zip
Z
Zipi Y Zape (S) (1989) [GAC Fast Line Fill].zip


 

Article créé le : Vendredi 15 Novembre 2013 à 22 h 23
Dernière mise à jour le : Dimanche 17 Novembre 2013 à 15 h 01
 
 

CPC-POWER/CPCArchives, projet maintenu par Fredouille.
Programmation par Kukulcan © 2007-2024 tous droits réservés.
Reproduction sans autorisation interdite. Tous les titres utilisées appartiennent à leurs propriétaires respectifs.