.........1.........2.........3.........4.........5.........6.........7.........8

LIGHT SCREEN DESIGNER
ZX Computing, May 1986
Part 12 of 13

Concluding Toni Baker's series with the second
half of last month's listing.


Light Screen Designer has been a feature in ZX for the past two years
and in this issue we bring you the last segment of the program. If you
have followed the series from the start you will find next month's
article invaluable. Toni Baker has written a manual to accompany the
program which will show you how to use Light Screen Designer to its
best advantage.

-----------------------------------------------------------------------------
E874 DDCB00FE PAINT     SET  7,(JFLAGS)    ;Signal "Now doing PAINT"
E878 CDCCDC             CALL MESSAGE
E87B 02                 DEFB #02           ;Input required paint colour
E87C 1807               JR   PAINTFILL

E87E DDCB00BE FILL      RES  7,(JFLAGS)    ;Signal "Now doing FILL"
E882 3A8D5C             LD   A,(ATTR_P)    ;A= current attribute byte
E885 E607     PAINTFILL AND  #07           ;A= required paint colour
E887 3249DB             LD   (NEW_COLOUR),A;Store paint colour
E88A 012000             LD   BC,#0020
E88D CD2EE8             CALL TEST_MEM      ;Store SCR2 if there is enough memory
E890 2100C0             LD   HL,#C000      ;Point HL to first  byte of SCR2
E893 1101C0             LD   DE,#C001      ;Point HL to second byte of SCR2
E896 01FF17             LD   BC,#17FF      ;BC= number of bytes in screen less 1
E899 3600               LD   (HL),#00      ;Clear first byte
E89B EDB0               LDIR               ;Clear remaining bytes
E89D 3A16DB             LD   A,(CURSOR+2)  ;A= pixel column number of cursor
E8A0 E607               AND  #07
E8A2 47                 LD   B,A
E8A3 04                 INC  B             ;B= position within byte of cursor
E8A4 3E01               LD   A,#01
E8A6 0F       PF_ALIGN  RRCA
E8A7 10FD               DJNZ PF_ALIGN      ;Align set bit to correct pos in A
E8A9 2A14DB             LD   HL,(CURSOR)   ;HL= address of screen byte
                                           ;containing cursor
E8AC F5                 PUSH AF
E8AD CD9EE7             CALL SR_PTRS       ;BC points to corresponding attr byte
                                           ;DE points to corresponding SCR2 byte
E8B0 F1                 POP  AF
E8B1 12                 LD   (DE),A        ;Set one pixel at cursor position,
                                           ;indicating a known interior point
E8B2 A6                 AND  (HL)
E8B3 0A                 LD   A,(BC)        ;A= attribute byte at cursor position
E8B4 2003               JR   NZ,PF_OLDCOL  ;Jump if cursor position is INKed
E8B6 0F                 RRCA
E8B7 0F                 RRCA
E8B8 0F                 RRCA
E8B9 E607     PF_OLDCOL AND  #07           ;A= colour of pixel at cursor pos
E8BB 3248DB             LD   (OLD_COLOUR),A;Store as the "old" interior colour
E8BE DDBE09             CP   (NEW_COLOUR)
E8C1 2005               JR   NZ,PF_BEGIN   ;Jump unless old colour same as new
E8C3 DDCB007E           BIT  7,(JFLAGS)
E8C7 C0                 RET  NZ            ;Return if doing PAINT
E8C8 DDCB00F6 PF_BEGIN  SET  6,(JFLAGS)    ;Signal "Not finished yet"
E8CC DDCB00A6           RES  4,(JFLAGS)    ;Signal "Scanning from top to bottom"
E8D0 DDCB00AE PF_LOOP   RES  5,(JFLAGS)    ;Signal "Scanning from left to right"
E8D4 CDAAE7             CALL SCAN_ROW      ;Scan row left to right
E8D7 DDCB00EE           SET  5,(JFLAGS)    ;Signal "Scanning from right to left"
E8DB CDAAE7             CALL SCAN_ROW      ;Scan row from right to left
E8DE DDCB0066           BIT  4,(JFLAGS)
E8E2 7C                 LD   A,H
E8E3 2009               JR   NZ,PFCHK_TOP  ;Jump if scanning from bottom to top
E8E5 FE57               CP   #57
E8E7 200D               JR   NZ,PF_CONT
E8E9 7D                 LD   A,L
E8EA FEA0               CP   #A0
E8EC 1806               JR   PFCHK_BOU
E8EE FE40     PFCHK_TOP CP   #40
E8F0 2004               JR   NZ,PF_CONT
E8F2 7D                 LD   A,L

E8F3 A7                 AND  A             ;Jump to change direction if at top
E8F4 285F     PFCHK_BOU JR   Z,PF_CHANGE   ;or bottom of screen
E8F6 C5                 PUSH BC            ;Stack attribute pointer
E8F7 D5                 PUSH DE            ;Stack SCR2 pointer
E8F8 E5                 PUSH HL            ;Stack screen pointer
E8F9 A7                 AND  A             ;Reset carry
E8FA 08                 EX   AF,AF'        ;Store reset carry in F' to signal
                                           ;"No new pixels marked"
E8FB D5                 PUSH DE
E8FC D9                 EXX
E8FD E1                 POP  HL
E8FE D9                 EXX                ;HL'= SCR2 pointer
E8FF 7C                 LD   A,H
E900 17                 RLA
E901 17                 RLA
E902 17                 RLA
E903 AC                 XOR  H
E904 E6C0               AND  #C0
E906 AC                 XOR  H
E907 67                 LD   H,A
E908 7D                 LD   A,L
E909 1F                 RRA
E90A 1F                 RRA
E90B AC                 XOR  H
E90C E638               AND  #38
E90E AC                 XOR  H
E90F 47                 LD   B,A           ;B= row number of current row
E910 DDCB0066           BIT  4,(JFLAGS)
E914 2002               JR   NZ,PF_1       ;Jump if scanning from bottom to top
E916 04                 INC  B
E917 04                 INC  B
E918 05       PF_1      DEC  B             ;B= row number of next row to scan
E919 0E00               LD   C,#00
E91B CD41DD             CALL PIX_ADDR      ;HL= address of new row
E91E CD9EE7             CALL SR_PTRS       ;BC= address of new attributes row
                                           ;DE= address of new SCR2 row
E921 C5                 PUSH BC            ;Stack attributes pointer
E922 D5                 PUSH DE            ;Stack SCR2 pointer
E923 E5                 PUSH HL            ;Stack screen pointer
E924 CD78E7   PF_LOOP_2 CALL COL_TEST      ;Test colour match for this square
E927 3004               JR   NC,PF_2       ;Jump unless just one colour matches
E929 2F                 CPL                ;A= 00(INK match) or FF(PAPER match)

E92A AE                 XOR  (HL)          ;A= next byte from screen, with each
                                           ;bit set if the colour matches the
                                           ;interior colour, reset otherwise
E92B 1802               JR   PF_3
E92D 280C     PF_2      JR   Z,PF_NEXT     ;Jump if the attribute does not
                                           ;contain the interior colour
E92F D9       PF_3      EXX
E930 A6                 AND  (HL)          ;Each bit will remain set only if
E931 D9                 EXX                ;the corresponding pixel is (a) the
                                           ;right colour, and (b) directly above
                                           ;(or below) a known interior pixel
E932 EB                 EX   DE,HL
E933 B6                 OR   (HL)          ;Also include any known interior
                                           ;pixel from this row
E934 77                 LD   (HL),A        ;Store in SCR2
E935 EB                 EX   DE,HL
E936 A7                 AND  A
E937 2802               JR   Z,PF_NEXT     ;Jump unless at least one pixel in
                                           ;this byte is known to be interior
E939 37                 SCF
E93A 08                 EX   AF,AF'        ;Store set carry to signal "At least
                                           ;one pixel on this row is interior"
E93B 03       PF_NEXT   INC  BC            ;Increment attributes pointer
E93C 13                 INC  DE            ;Increment SCR2 pointer
E93D 23                 INC  HL            ;Increment screen pointer
E93E D9                 EXX
E93F 23                 INC  HL            ;Increment SCR2 pointer to row above
E940 D9                 EXX                ;(or below)
E941 7D                 LD   A,L
E942 E61F               AND  #1F
E944 20DE               JR   NZ,PF_LOOP_2  ;Jump back unless at end of row
E946 E1                 POP  HL            ;Screen pointer now at start of row
E947 D1                 POP  DE            ;SCR2 pointer now at start of row
E948 C1                 POP  BC            ;Attribute pointer at start of row
E949 08                 EX   AF,AF'        ;Retrieve carry flag
E94A 3006               JR   NC,PFCHANGE1  ;Jump if there were no known interior
                                           ;points on this row

E94C F1                 POP  AF
E94D F1                 POP  AF
E94E F1                 POP  AF
E94F C3D0E8   PF_JUMP   JP   PF_LOOP       ;Jump to scan next row
E952 E1       PFCHANGE1 POP  HL            ;Screen pointer now at start of
                                           ;previous row
E953 D1                 POP  DE            ;Same for SCR2 pointer
E954 C1                 POP  BC            ;and for attribute pointer
E955 3A40DB   PF_CHANGE LD   A,(JFLAGS)
E958 EE50               XOR  #50           ;Change scan direction flag and
E95A 3240DB             LD   (JFLAGS),A    ;"Finished yet?" flag
E95D CB77               BIT  6,A
E95F 28EE               JR   Z,PF_JUMP     ;Jump back unless finished
E961 010058             LD   BC,#5800      ;BC points to first attribute byte
E964 1100C0             LD   DE,#C000      ;DE points to first SCR2 byte
E967 210040             LD   HL,#4000      ;HL points to first screen byte
E96A 3A49DB             LD   A,(NEW_COLOUR);A= colour to paint
E96D 07                 RLCA
E96E 07                 RLCA
E96F 07                 RLCA
E970 3248DB             LD   (OLD_COLOUR),A;Store 8*colour
E973 E5       PF_SQLOOP PUSH HL            ;Stack screen pointer
E974 D5                 PUSH DE            ;Stack SCR2 pointer
E975 C5                 PUSH BC            ;Stack attribute pointer
E976 010008             LD   BC,#0800
E979 1A       PF_SQUARE LD   A,(DE)        ;A= next byte from SCR2
E97A A6                 AND  (HL)
E97B 2802               JR   Z,PF_P_EXT
E97D CBD9               SET  3,C           ;Set flag if you come across an
                                           ;INKed interior point
E97F 1A       PF_P_EXT  LD   A,(DE)
E980 2F                 CPL
E981 B6                 OR   (HL)
E982 3C                 INC  A
E983 2802               JR   Z,PF_I_EXT
E985 CBD1               SET  2,C           ;Set flag if you come across a
                                           ;PAPERed interior point
E987 1A       PF_I_EXT  LD   A,(DE)
E988 2F                 CPL
E989 A6                 AND  (HL)
E98A 2802               JR   Z,PF_P_INT
E98C CBC9               SET  1,C           ;Set flag if you come across an
                                           ;INKed exterior point
E98E 1A       PF_P_INT  LD   A,(DE)
E98F B6                 OR   (HL)
E990 3C                 INC  A
E991 2802               JR   Z,PF_I_INT
E993 CBC1               SET  0,C           ;Set flag if you come across a
                                           ;PAPERed exterior point
E995 14       PF_I_INT  INC  D             ;SCR2 pointer to next row
E996 24                 INC  H             ;Screen pointer to next row
E997 10E0               DJNZ PF_SQUARE     ;Repeat for all rows of char square
E999 0608               LD   B,#08
E99B 79                 LD   A,C
E99C D604               SUB  #04

E99E 385B               JR   C,PF_NXT_SQ   ;Jump if every pixel in the square
                                           ;is exterior
E9A0 DDCB007E           BIT  7,(JFLAGS)
E9A4 280A               JR   Z,PFSETLOOP   ;Jump if doing FILL
E9A6 A7                 AND  A
E9A7 2843               JR   Z,PF_ALL_PP   ;Jump if every pixel is a PAPERed
                                           ;interior point
E9A9 D602               SUB  #02
E9AB 2833               JR   Z,PF_CH_PP    ;Jump if this is a boundary square
                                           ;with paper interior, ink exterior
E9AD 3D                 DEC  A
E9AE 2009               JR   NZ,PF_A1      ;Jump unless the square contains an
                                           ;INK boundary separating two PAPER
                                           ;regions, one interior, one exterior
E9B0 15       PFSETLOOP DEC  D             ;SCR2 pointer to next row
E9B1 25                 DEC  H             ;Screen pointer to next row
E9B2 1A                 LD   A,(DE)
E9B3 B6                 OR   (HL)
E9B4 77                 LD   (HL),A        ;INK all interior pixels
E9B5 10F9               DJNZ PFSETLOOP     ;Repeat for whole character square
E9B7 1811               JR   PF_CH_INK
E9B9 3D       PF_A1     DEC  A
E9BA 200B               JR   NZ,PF_A2      ;Jump unless every pixel is INKed
                                           ;and interior
E9BC AF                 XOR  A
E9BD DDCB086E           BIT  5,(OLD_COLOUR)
E9C1 200C               JR   NZ,PFSET_INK  ;Jump if new colour is light
E9C3 3E38               LD   A,#38         ;Set paper colour to white
E9C5 1808               JR   PFSET_INK     ;Jump to change attribute byte
E9C7 3D       PF_A2     DEC  A
E9C8 200A               JR   NZ,PF_A3      ;Jump unless this is a boundary sqr
                                           ;with ink interior, paper exterior
E9CA C1       PF_CH_INK POP  BC
E9CB 0A                 LD   A,(BC)        ;A= attribute byte of current square
E9CC C5                 PUSH BC
E9CD E638               AND  #38           ;Isolate paper colour
E9CF DDB609   PFSET_INK OR   (NEW_COLOUR)  ;Change ink colour
E9D2 1824               JR   PFST_ATTR
E9D4 D602     PF_A3     SUB  #02
E9D6 200F               JR   NZ,PFCLRLOOP  ;Jump unless the square contains a
                                           ;PAPER boundary separating two INK
                                           ;regions, one interior, one exterior

E9D8 15       PRRESLOOP DEC  D             ;SCR2 pointer to next row
E9D9 25                 DEC  H             ;Screen pointer to next row
E9DA 1A                 LD   A,(DE)
E9DB 2F                 CPL
E9DC A6                 AND  (HL)
E9DD 77                 LD   (HL),A        ;PAPER all interior pixels
E9DE 10F8               DJNZ PRRESLOOP     ;Repeat for whole character square
E9E0 C1       PF_CH_PP  POP  BC
E9E1 0A                 LD   A,(BC)        ;A= attribute byte of current square
E9E2 C5                 PUSH BC
E9E3 E607               AND  #07           ;Isolate ink colour
E9E5 180E               JR   PF_SET_PP
E9E7 25       PFCLRLOOP DEC  H             ;Screen pointer to next row
E9E8 3600               LD   (HL),#00      ;PAPER every pixel
E9EA 10FB               DJNZ PFCLRLOOP     ;Repeat for whole character square
E9EC AF       PF_ALL_PP XOR  A             ;A= 00 (ink black)
E9ED DDCB0956           BIT  2,(NEW_COLOUR)
E9F1 2002               JR   NZ,PF_SET_PP  ;Jump if new colour is light
E9F3 3E07               LD   A,#07         ;Set ink colour to white
E9F5 DDB608   PF_SET_PP OR   (OLD_COLOUR)  ;Change paper colour to new colour
E9F8 C1       PFST_ATTR POP  BC
E9F9 02                 LD   (BC),A        ;Store new attribute byte
E9FA C5                 PUSH BC
E9FB C1       PF_NXT_SQ POP  BC            ;BC= attribute pointer
E9FC D1                 POP  DE            ;DE= SCR2 pointer
E9FD E1                 POP  HL            ;HL= screen pointer
E9FE 03                 INC  BC            ;Increment attribute pointer
E9FF 13                 INC  DE            ;Increment SCR2 pointer
EA00 23                 INC  HL            ;Increment screen pointer
EA01 7D                 LD   A,L
EA02 A7                 AND  A
EA03 2009               JR   NZ,PF_J2      ;Jump unless at end of "third"
                                           ;of screen
EA05 7A                 LD   A,D
EA06 C607               ADD  A,#07
EA08 57                 LD   D,A           ;DE points to next square
EA09 E67F               AND  #7F
EA0B 67                 LD   H,A           ;HL points to next square
EA0C FE58               CP   #58
EA0E C273E9   PF_J2     JP   NZ,PF_SQLOOP  ;Jump back unless at end of screen
EA11 C9                 RET
-----------------------------------------------------------------------------
EA12 3E40     CURS_TYPE LD   A,#40
EA14 C32ADF             JP   CT_H
-----------------------------------------------------------------------------
