GLOBAL TRUE, FALSE TRUE = -1 DIM GLOBAL PXL_MASKS(159),PXL_MASKX(159),PXL_MASKR(159),PXL_MASKW(159),PXL_MASKL(159) GLOBAL PXL_PXHI, PXL_PYHI, PXL_FXHI, PXL_FYHI, PXL_PAL1, PXL_PAL2, PXL_DIRADDR, PXL_DIRSIZE GLOBAL PXL_RBUFADDR,PXL_RBUFSIZE,PXL_RBUFDATASIZE,PXL_RBUFDATASTEP,PXL_RCOPYSIZE,PXL_RFULL DIM GLOBAL PXL_XADDR( 159 ), PXL_YADDR( 127 ), PXL_RSRC( 127 ), PXL_RDST( 127 ) GLOBAL PXL_SPRITEADDR, PXL_TEXTADDR, PXL_USETXMETA, PXL_TXMETAADDR, PXL_FONT, PXL_CAPSLOCK 'PXL LIBRARY 2.0, BY NATHANIEL R. BABIAK, ED. NOVEMBER 16, 2020 BG 1 BG SOURCE ROM(3) CALL PXL_INIT( ROM(4) ) BG 0 CALL PXL_PALETTE( 3, 3, 3 ) CALL MAIN END SUB MAIN CALL SET_TEST CALL STRAIGHT_LINE_TEST CALL RECT_TEST CALL CIRCFILL_TEST CALL CIRC_TEST 'NOW THE REAL TEST... PRINT "BENCHMARK" PRINT "(FOR 3D)" T = TIMER CALL LINE_TEST FRAMES = TIMER - T LINES = 2 * ( PXL_PXHI + PXL_PYHI ) * 4 'NEVER FAST ENOUGH! PRINT "FRAMES USED: ", FRAMES PRINT "SEC (60FPS):", INT( FRAMES / 60 * 100 + 0.5 ) / 100 PRINT "LINES DRAWN:", LINES PRINT "LINES/FRAME:", INT( LINES / FRAMES * 100 + 0.5 ) / 100 END SUB SUB SET_TEST AREA = PXL_PXHI * PXL_PYHI SEQUENCE = 1 'FILL SCREEN CALL PXL_RECT( 0, 0, PXL_PXHI - 1, PXL_PYHI - 1, 1, FALSE ) FOR MODE = -1 TO 1 IF MODE <> -1 THEN MODE = MODE XOR 1 REPEAT DEC SEQUENCE IF SEQUENCE < AREA THEN CALL PXL_SETP( SEQUENCE \ PXL_PYHI, SEQUENCE MOD PXL_PYHI, MODE, FALSE ) END IF INC SEQUENCE IF ( SEQUENCE AND 1 ) <> 0 XOR ( SEQUENCE AND $4000 ) <> 0 THEN ADD SEQUENCE, 32768 SEQUENCE = SEQUENCE \ 2 UNTIL SEQUENCE = 1 IF MODE <> -1 THEN MODE = MODE XOR 1 NEXT MODE END SUB SUB STRAIGHT_LINE_TEST FOR I = 1 TO 100 X1 = RND( PXL_PXHI - 1 ) X2 = RND( PXL_PXHI - 1 ) Y = RND( PXL_PYHI - 1 ) IF X1 > X2 THEN SWAP X1, X2 CALL PXL_HORZ( X1, X2, Y, RND( 2 ) - 1, FALSE ) X = RND( PXL_PXHI - 1 ) Y1 = RND( PXL_PYHI - 1 ) Y2 = RND( PXL_PYHI - 1 ) IF Y1 > Y2 THEN SWAP Y1, Y2 CALL PXL_VERT( X, Y1, Y2, RND( 2 ) - 1, FALSE ) NEXT I FOR Y = 0 TO PXL_PYHI - 1 CALL PXL_HORZ( 0, PXL_PXHI - 1, Y, -1, FALSE ) IF Y AND 2 THEN WAIT VBL NEXT Y FOR X = 0 TO PXL_PXHI - 1 CALL PXL_VERT( X, 0, PXL_PYHI - 1, -1, FALSE ) IF X AND 2 THEN WAIT VBL NEXT X FOR Y = 0 TO PXL_PYHI - 1 CALL PXL_HORZ( 0, PXL_PXHI - 1, Y, 0, FALSE ) IF Y AND 2 THEN WAIT VBL NEXT Y END SUB SUB RECT_TEST FOR I = 1 TO 50 X1 = RND( PXL_PXHI - 1 ) X2 = RND( PXL_PXHI - 1 ) IF X1 > X2 THEN SWAP X1, X2 Y1 = RND( PXL_PYHI - 1 ) Y2 = RND( PXL_PYHI - 1 ) IF Y1 > Y2 THEN SWAP Y1, Y2 M = RND( 2 ) - 1 CALL PXL_RECT( X1, Y1, X2, Y2, M, FALSE ) NEXT I X = PXL_PXHI \ 2 Y = PXL_PYHI \ 2 FOR J = 1 TO 3 IF J = 1 THEN MODE = -1 IF J = 2 THEN MODE = 1 IF J = 3 THEN MODE = 0 SIDE = MIN( X, Y ) IF MODE <> -1 THEN ADD SIDE, SIDE FOR I = 0 TO SIDE X1 = X - I \ 2 Y1 = Y - I \ 2 X2 = X1 + I - 1 Y2 = Y1 + I - 1 CALL PXL_RECT( X1, Y1, X2, Y2, MODE, FALSE ) IF MODE = -1 THEN WAIT VBL CALL PXL_RECT( X1, Y1, X2, Y2, MODE, FALSE ) END IF NEXT I IF MODE = -1 THEN DEC I CALL PXL_RECT( X1, Y1, X2, Y2, MODE, FALSE ) END IF NEXT J CALL PXL_CLS END SUB SUB CIRCFILL_TEST FOR I = 1 TO 50 X1 = RND( PXL_PXHI - 1 ) X2 = RND( PXL_PXHI - 1 ) IF X1 > X2 THEN SWAP X1, X2 Y1 = RND( PXL_PYHI - 1 ) Y2 = RND( PXL_PYHI - 1 ) IF Y1 > Y2 THEN SWAP Y1, Y2 XC = ( X1 + X2 ) \ 2 YC = ( Y1 + Y2 ) \ 2 W = X2 - X1 + 1 H = Y2 - Y1 + 1 R = MIN( W, H ) \ 2 M = RND( 2 ) - 1 CALL PXL_CIRCFILL( XC, YC, R, M, FALSE ) NEXT I XC = PXL_PXHI \ 2 YC = PXL_PYHI \ 2 FOR J = 1 TO 3 R2 = MIN( PXL_PXHI, PXL_PYHI ) \ 4 - 1 IF J = 1 THEN MODE = -1 IF J = 2 THEN MODE = 1 IF J = 3 THEN MODE = 0 IF MODE <> -1 THEN ADD R2, R2 FOR R = 0 TO R2 CALL PXL_CIRCFILL( XC, YC, R, MODE, FALSE ) IF MODE = -1 THEN WAIT VBL CALL PXL_CIRCFILL( XC, YC, R, -1, FALSE ) END IF NEXT R IF MODE = -1 THEN CALL PXL_CIRCFILL( XC, YC, R2, -1, FALSE ) END IF NEXT J 'R = MAX( PXL_PXHI, PXL_PYHI ) + 5 'THAT DOESN'T WORK ANYMORE... CLIPPED CIRCLE IS BROKEN!!! R = MAX( PXL_PXHI, PXL_PYHI ) CALL PXL_CIRCFILL_CLIP( PXL_PXHI - 1, 0, R, 1, FALSE ) WAIT 60 CALL PXL_CIRCFILL_CLIP( PXL_PXHI - 1, PXL_PYHI - 1, R, -1, FALSE ) WAIT 60 CALL PXL_CLS END SUB SUB CIRC_TEST 'FOR R = 1 TO 205 STEP 3 'THAT DOESN'T WORK ANYMORE... CLIPPED CIRCLE IS BROKEN!!! FOR R = 1 TO PXL_PXHI - 1 STEP 3 CALL PXL_CIRC_CLIP( PXL_PXHI - 1, 0, R, -1, FALSE ) CALL PXL_CIRC_CLIP( 0, 0, R, -1, FALSE ) CALL PXL_CIRC_CLIP( 0, PXL_PYHI - 1, R, -1, FALSE ) CALL PXL_CIRC_CLIP( PXL_PXHI - 1, PXL_PYHI - 1, R, -1, FALSE ) NEXT R CALL PXL_CLS END SUB SUB LINE_TEST FOR I = 1 TO 4 IF I = 1 THEN MODE = -1 IF I = 2 THEN MODE = 1 IF I = 3 THEN MODE = -1 IF I = 4 THEN MODE = 0 FOR X = PXL_PXHI \ 2 TO PXL_PXHI - 1 CALL PXL_LINE( PXL_PXHI \ 2, PXL_PYHI \ 2 - 1, X, 0, MODE, FALSE ) NEXT X FOR Y = 1 TO PXL_PYHI \ 2 - 1 CALL PXL_LINE( PXL_PXHI \ 2, PXL_PYHI \ 2 - 1, PXL_PXHI - 1, Y, MODE, FALSE ) NEXT Y FOR Y = PXL_PYHI \ 2 TO PXL_PYHI - 2 CALL PXL_LINE( PXL_PXHI \ 2, PXL_PYHI \ 2, PXL_PXHI - 1, Y, MODE, FALSE ) NEXT Y FOR X = PXL_PXHI - 1 TO PXL_PXHI \ 2 STEP -1 CALL PXL_LINE( PXL_PXHI \ 2, PXL_PYHI \ 2, X, PXL_PYHI - 1, MODE, FALSE ) NEXT X FOR X = PXL_PXHI \ 2 - 1 TO 0 STEP -1 CALL PXL_LINE( PXL_PXHI \ 2 - 1, PXL_PYHI \ 2, X, PXL_PYHI - 1, MODE, FALSE ) NEXT X FOR Y = PXL_PYHI - 2 TO PXL_PYHI / 2 STEP -1 CALL PXL_LINE( PXL_PXHI \ 2 - 1, PXL_PYHI \ 2, 0, Y, MODE, FALSE ) NEXT Y FOR Y = PXL_PYHI \ 2 - 1 TO 1 STEP -1 CALL PXL_LINE( PXL_PXHI \ 2 - 1, PXL_PYHI \ 2 - 1, 0, Y, MODE, FALSE ) NEXT Y FOR X = 0 TO PXL_PXHI \ 2 - 1 CALL PXL_LINE( PXL_PXHI \ 2 - 1, PXL_PYHI \ 2 - 1, X, 0, MODE, FALSE ) NEXT X NEXT I END SUB '^~.,,,.~^```^~.,,,.~^```^~.,,,.~^HAPPY CODING!^~.,,,.~^```^~.,,,.~^```^~.,,,.~^ SUB ESCSEQ( RETURN_S$ ) NEW$ = "" USE_ESCAPE = FALSE USE_CAPSLOCK = FALSE FOR P = 1 TO LEN( RETURN_S$ ) C = ASC( MID$( RETURN_S$, P, 1 ) ) IS_LETTER = C >= 65 AND C <= 90 IF C = 92 AND NOT USE_ESCAPE THEN USE_ESCAPE = TRUE ELSE USE_SHIFT = FALSE IF USE_ESCAPE THEN IF C = 39 THEN C = 34 IF C = 43 THEN USE_CAPSLOCK = NOT USE_CAPSLOCK IF C = 46 THEN C = 10 IF IS_LETTER THEN USE_SHIFT = TRUE END IF IF C = 34 OR C = 10 OR IS_LETTER OR NOT USE_ESCAPE THEN IF IS_LETTER AND NOT( USE_CAPSLOCK XOR USE_SHIFT ) THEN ADD C, 32 NEW$ = NEW$ + CHR$( C ) END IF USE_ESCAPE = FALSE END IF NEXT P RETURN_S$ = NEW$ END SUB SUB PXL_SOURCE( SPRITEROM, TEXTROM, TXMETAROM, F ) PXL_SPRITEADDR = ROM( SPRITEROM ) PXL_TEXTADDR = ROM( TEXTROM ) PXL_USETXMETA = TXMETAROM >= 0 IF PXL_USETXMETA THEN PXL_TXMETAADDR = ROM( TXMETAROM ) PXL_FONT = F - 32 END SUB SUB PXL_INIT( R ) FOR PX = 0 TO 159 BIT = 7 - PX MOD 8 PXL_MASKS( PX ) = 2 ^ BIT PXL_MASKX( PX ) = 2 ^ BIT XOR $FF PXL_MASKR( PX ) = 2 ^ ( BIT + 1 ) - 1 PXL_MASKW( PX ) = PXL_MASKR( PX ) XOR $FF PXL_MASKL( PX ) = 2 ^ BIT - 1 XOR $FF NEXT PX PXL_PXHI = PEEK( R + 2 ) PXL_PYHI = PEEK( R + 3 ) PXL_FXHI = PXL_PXHI + 0.5 PXL_FYHI = PXL_PYHI + 0.5 PXL_PAL1 = PEEK( R + 4 ) PXL_PAL2 = PEEK( R + 5 ) PXL_DIRADDR = PEEKW( R + 6 ) + 32768 PXL_DIRSIZE = PEEKW( R + 8 ) + 32768 PXL_RBUFADDR = PEEKW( R + 10 ) + 32768 PXL_RBUFSIZE = PEEKW( R + 12 ) + 32768 PXL_RBUFDATASIZE = PEEKW( R + 14 ) + 32768 PXL_RBUFDATASTEP = PEEKW( R + 16 ) + 32768 PXL_RCOPYSIZE = PEEK( R + 18 ) PXL_RFULL = PEEK( R + 19 ) A = R + 20 FOR C = 0 TO 159 STEP 8 FOR P = 0 TO 7 PXL_XADDR( C + P ) = PEEKW( A ) + 32768 IF C <= 127 THEN PXL_YADDR( C + P ) = PEEKW( A + 2 ) + P + 32768 NEXT P IF C <= 127 THEN ADD A, 4 ELSE ADD A, 2 NEXT C IF PXL_RCOPYSIZE THEN FOR CR = 0 TO 120 STEP 8 PXL_RSRC( CR ) = PEEKW( A ) + 32768 PXL_RDST( CR ) = PEEKW( A + 2 ) + 32768 IF PXL_RDST( CR ) THEN FOR P = 1 TO 7 PXL_RSRC( CR + P ) = PXL_RSRC( CR ) + P * PXL_RCOPYSIZE PXL_RDST( CR + P ) = PXL_RDST( CR ) + P * PXL_RCOPYSIZE NEXT P END IF ADD A, 4 NEXT CR IF PXL_RFULL THEN ON RASTER CALL PXL_RBUF1 ELSE ON RASTER CALL PXL_RBUF0 END IF CALL PXL_CLS WAIT VBL BG COPY 0, 0, 20, 16 TO 0, 0 END SUB SUB PXL_RBUF1 COPY PXL_RSRC( RASTER ), PXL_RCOPYSIZE TO PXL_RDST( RASTER ) END SUB SUB PXL_RBUF0 IF PXL_RDST( RASTER ) THEN COPY PXL_RSRC( RASTER ), PXL_RCOPYSIZE TO PXL_RDST( RASTER ) END SUB SUB PXL_CLS FILL PXL_DIRADDR, PXL_DIRSIZE IF PXL_RBUFDATASIZE THEN A2 = PXL_RBUFADDR + PXL_RBUFSIZE - 1 FOR A = PXL_RBUFADDR TO A2 STEP PXL_RBUFDATASTEP FILL A, PXL_RBUFDATASIZE NEXT A ELSE FILL PXL_RBUFADDR, PXL_RBUFSIZE END IF END SUB SUB PXL_PALETTE( RED, GREEN, BLUE ) LO = COLOR( 0, 0 ) HI = RED * 16 + GREEN * 4 + BLUE PALETTE PXL_PAL1, LO, HI, LO, HI PALETTE PXL_PAL2, LO, LO, HI, HI END SUB SUB PXL_SETP( PX, PY, MODE, USE_HI ) DST = PXL_XADDR( PX ) + PXL_YADDR( PY ) + ( 8 AND USE_HI ) IF MODE = 1 THEN POKE DST, PEEK( DST ) OR PXL_MASKS( PX ) ELSE IF MODE THEN POKE DST, PEEK( DST ) XOR PXL_MASKS( PX ) ELSE POKE DST, PEEK( DST ) AND PXL_MASKX( PX ) END IF END SUB SUB PXL_SETP_CLIP( PX, PY, MODE, USE_HI ) IF PX < 0 OR PX >= PXL_PXHI OR PY < 0 OR PY >= PXL_PYHI THEN EXIT SUB DST = PXL_XADDR( PX ) + PXL_YADDR( PY ) + ( 8 AND USE_HI ) IF MODE = 1 THEN POKE DST, PEEK( DST ) OR PXL_MASKS( PX ) ELSE IF MODE THEN POKE DST, PEEK( DST ) XOR PXL_MASKS( PX ) ELSE POKE DST, PEEK( DST ) AND PXL_MASKX( PX ) END IF END SUB SUB PXL_SETF( FX, FY, MODE, USE_HI ) DST = PXL_XADDR( FX + 0.5 ) + PXL_YADDR( FY + 0.5 ) + ( 8 AND USE_HI ) IF MODE = 1 THEN POKE DST, PEEK( DST ) OR PXL_MASKS( FX + 0.5 ) ELSE IF MODE THEN POKE DST, PEEK( DST ) XOR PXL_MASKS( FX + 0.5 ) ELSE POKE DST, PEEK( DST ) AND PXL_MASKX( FX + 0.5 ) END IF END SUB SUB PXL_SETF_CLIP( FX, FY, MODE, USE_HI ) IF FX < -0.5 OR FX >= PXL_FXHI OR FY <= -0.5 OR FY >= PXL_FYHI THEN EXIT SUB DST = PXL_XADDR( FX + 0.5 ) + PXL_YADDR( FY + 0.5 ) + ( 8 AND USE_HI ) IF MODE = 1 THEN POKE DST, PEEK( DST ) OR PXL_MASKS( FX + 0.5 ) ELSE IF MODE THEN POKE DST, PEEK( DST ) XOR PXL_MASKS( FX + 0.5 ) ELSE POKE DST, PEEK( DST ) AND PXL_MASKX( FX + 0.5 ) END IF END SUB SUB PXL_TESTP( PX, PY, USE_HI, RETURN_FLAG ) DST = PXL_XADDR( PX ) + PXL_YADDR( PY ) + ( 8 AND USE_HI ) RETURN_FLAG = ( PEEK( DST ) AND PXL_MASKS( PX ) ) <> FALSE END SUB SUB PXL_TESTP_CLIP( PX, PY, USE_HI, RETURN_FLAG ) IF PX < 0 OR PX >= PXL_PXHI OR PY < 0 OR PY >= PXL_PYHI THEN EXIT SUB DST = PXL_XADDR( PX ) + PXL_YADDR( PY ) + ( 8 AND USE_HI ) RETURN_FLAG = ( PEEK( DST ) AND PXL_MASKS( PX ) ) <> FALSE END SUB SUB PXL_TESTF( FX, FY, USE_HI, RETURN_FLAG ) DST = PXL_XADDR( FX + 0.5 ) + PXL_YADDR( FY + 0.5 ) + ( 8 AND USE_HI ) RETURN_FLAG = ( PEEK( DST ) AND PXL_MASKS( FX + 0.5 ) ) <> FALSE END SUB SUB PXL_TESTF_CLIP( FX, FY, USE_HI, RETURN_FLAG ) IF FX < -0.5 OR FX >= PXL_FXHI OR FY <= -0.5 OR FY >= PXL_FYHI THEN EXIT SUB DST = PXL_XADDR( FX + 0.5 ) + PXL_YADDR( FY + 0.5 ) + ( 8 AND USE_HI ) RETURN_FLAG = ( PEEK( DST ) AND PXL_MASKS( FX + 0.5 ) ) <> FALSE END SUB SUB PXL_VERT( FX, FY1, FY2, MODE, USE_HI ) ADDR = PXL_XADDR( FX + 0.5 ) + ( 8 AND USE_HI ) PY_HI = INT( FY2 + 0.5 ) IF MODE = 1 THEN MASKS = PXL_MASKS( FX + 0.5 ) FOR PY = INT( FY1 + 0.5 ) TO PY_HI POKE ADDR + PXL_YADDR( PY ), PEEK( ADDR + PXL_YADDR( PY ) ) OR MASKS NEXT PY ELSE IF MODE THEN MASKS = PXL_MASKS( FX + 0.5 ) FOR PY = INT( FY1 + 0.5 ) TO PY_HI POKE ADDR + PXL_YADDR( PY ), PEEK( ADDR + PXL_YADDR( PY ) ) XOR MASKS NEXT PY ELSE MASKX = PXL_MASKX( FX + 0.5 ) FOR PY = INT( FY1 + 0.5 ) TO PY_HI POKE ADDR + PXL_YADDR( PY ), PEEK( ADDR + PXL_YADDR( PY ) ) AND MASKX NEXT PY END IF END SUB SUB PXL_VERT_CLIP( FX, FY1, FY2, MODE, USE_HI ) IF -0.5 <= FX AND FX < PXL_FXHI AND -0.5 <= FY2 AND FY1 < PXL_FYHI THEN CALL PXL_VERT( FX, MAX( 0, FY1 ), MIN( PXL_PYHI - 1, FY2 ), MODE, USE_HI ) END SUB SUB PXL_HORZ( FX1, FX2, FY, MODE, USE_HI ) PX = FX1 + 0.5 AND %11111000 PX_HI = ( FX2 + 0.5 AND %11111000 ) - 8 IF PX = PX_HI + 8 THEN MASK1 = PXL_MASKR( FX1 + 0.5 ) AND PXL_MASKL( FX2 + 0.5 ) USE_MASK2 = FALSE ELSE MASK1 = PXL_MASKR( FX1 + 0.5 ) USE_MASK2 = TRUE MASK2 = PXL_MASKL( FX2 + 0.5 ) END IF ADDR = PXL_YADDR( FY + 0.5 ) + ( 8 AND USE_HI ) IF MODE = 1 THEN POKE ADDR+PXL_XADDR(PX), PEEK(ADDR+PXL_XADDR(PX)) OR MASK1 FOR PX = PX + 8 TO PX_HI STEP 8 POKE ADDR+PXL_XADDR(PX), $FF NEXT PX IF USE_MASK2 THEN POKE ADDR+PXL_XADDR(PX), PEEK(ADDR+PXL_XADDR(PX)) OR MASK2 ELSE IF MODE THEN POKE ADDR+PXL_XADDR(PX), PEEK(ADDR+PXL_XADDR(PX)) XOR MASK1 FOR PX = PX + 8 TO PX_HI STEP 8 POKE ADDR+PXL_XADDR(PX), NOT PEEK(ADDR+PXL_XADDR(PX)) NEXT PX IF USE_MASK2 THEN POKE ADDR+PXL_XADDR(PX), PEEK(ADDR+PXL_XADDR(PX)) XOR MASK2 ELSE POKE ADDR+PXL_XADDR(PX), PEEK(ADDR+PXL_XADDR(PX)) AND NOT MASK1 FOR PX = PX + 8 TO PX_HI STEP 8 POKE ADDR+PXL_XADDR(PX), 0 NEXT PX IF USE_MASK2 THEN POKE ADDR+PXL_XADDR(PX), PEEK(ADDR+PXL_XADDR(PX)) AND NOT MASK2 END IF END SUB SUB PXL_HORZ_CLIP( FX1, FX2, FY, MODE, USE_HI ) IF -0.5 <= FX2 AND FX1 < 159.5 AND -0.5 <= FY AND FY < 127.5 THEN CALL PXL_HORZ( MAX( 0, FX1 ), MIN( 159, FX2 ), FY, MODE, USE_HI ) END SUB SUB PXL_CIRC( FX, FY, FR, MODE, USE_HI ) 'FR IS MERELY SANITIZED TO PR. PX = INT( FX + 0.5 ) PY = INT( FY + 0.5 ) PR = INT( FR + 0.5 ) PR_SQD = PR ^ 2 'DEC HERE (-1.0) RATHER THAN THE "FOR" LOOP, ROUND INT (+0.5), SUBTRACT 0.25 EMPIRICALLY. A_MINUS_ONE = INT( 0.7071 * PR - 0.75 ) 'DEC WHEN PR=4 OR PR=11 SO IT'S PIXEL-PERFECT. IF PR = 4 OR PR = 11 THEN DEC A_MINUS_ONE FOR NEG_A = -A_MINUS_ONE - 1 TO A_MINUS_ONE B = INT( SQR( PR_SQD - NEG_A ^ 2 ) + 0.5 ) IF B < PR THEN CALL PXL_SETP( PX - NEG_A, PY + B, MODE, USE_HI ) CALL PXL_SETP( PX - B, PY - NEG_A, MODE, USE_HI ) CALL PXL_SETP( PX + NEG_A, PY - B, MODE, USE_HI ) CALL PXL_SETP( PX + B, PY + NEG_A, MODE, USE_HI ) ELSE CALL PXL_HORZ( PX + NEG_A, PX - NEG_A, PY - B, MODE, USE_HI ) CALL PXL_HORZ( PX + NEG_A, PX - NEG_A, PY + B, MODE, USE_HI ) CALL PXL_VERT( PX - B, PY + NEG_A, PY - NEG_A, MODE, USE_HI ) CALL PXL_VERT( PX + B, PY + NEG_A, PY - NEG_A, MODE, USE_HI ) NEG_A = -NEG_A END IF NEXT NEG_A 'UNROLL THE LAST ITERATION TO SAVE CC. THE STRAIGHT LINES ARE TOO FAR WHEN PR=2. B = INT( SQR( PR_SQD - NEG_A ^ 2 ) + 0.5 ) IF NEG_A <> B AND PR <> 2 THEN CALL PXL_SETP( PX - NEG_A, PY + B, MODE, USE_HI ) CALL PXL_SETP( PX - B, PY - NEG_A, MODE, USE_HI ) CALL PXL_SETP( PX + NEG_A, PY - B, MODE, USE_HI ) CALL PXL_SETP( PX + B, PY + NEG_A, MODE, USE_HI ) END IF END SUB SUB PXL_CIRC_CLIP( FX, FY, FR, MODE, USE_HI ) 'FR IS MERELY SANITIZED TO PR. PX = INT( FX + 0.5 ) PY = INT( FY + 0.5 ) PR = INT( FR + 0.5 ) PR_SQD = PR ^ 2 'DEC HERE (-1.0) RATHER THAN THE "FOR" LOOP, ROUND INT (+0.5), SUBTRACT 0.25 EMPIRICALLY. A_MINUS_ONE = INT( 0.7071 * PR - 0.75 ) 'DEC WHEN PR=4 OR PR=11 SO IT'S PIXEL-PERFECT. IF PR = 4 OR PR = 11 THEN DEC A_MINUS_ONE FOR NEG_A = -A_MINUS_ONE - 1 TO A_MINUS_ONE B = INT( SQR( PR_SQD - NEG_A ^ 2 ) + 0.5 ) IF B < PR THEN CALL PXL_SETP_CLIP( PX - NEG_A, PY + B, MODE, USE_HI ) CALL PXL_SETP_CLIP( PX - B, PY - NEG_A, MODE, USE_HI ) CALL PXL_SETP_CLIP( PX + NEG_A, PY - B, MODE, USE_HI ) CALL PXL_SETP_CLIP( PX + B, PY + NEG_A, MODE, USE_HI ) ELSE CALL PXL_HORZ_CLIP( PX + NEG_A, PX - NEG_A, PY - B, MODE, USE_HI ) CALL PXL_HORZ_CLIP( PX + NEG_A, PX - NEG_A, PY + B, MODE, USE_HI ) CALL PXL_VERT_CLIP( PX - B, PY + NEG_A, PY - NEG_A, MODE, USE_HI ) CALL PXL_VERT_CLIP( PX + B, PY + NEG_A, PY - NEG_A, MODE, USE_HI ) NEG_A = -NEG_A END IF NEXT NEG_A 'UNROLL THE LAST ITERATION TO SAVE CC. THE STRAIGHT LINES ARE TOO FAR WHEN PR=2. B = INT( SQR( PR_SQD - NEG_A ^ 2 ) + 0.5 ) IF NEG_A <> B AND PR <> 2 THEN CALL PXL_SETP_CLIP( PX - NEG_A, PY + B, MODE, USE_HI ) CALL PXL_SETP_CLIP( PX - B, PY - NEG_A, MODE, USE_HI ) CALL PXL_SETP_CLIP( PX + NEG_A, PY - B, MODE, USE_HI ) CALL PXL_SETP_CLIP( PX + B, PY + NEG_A, MODE, USE_HI ) END IF END SUB ' SUB PXL_CIRCFAST( FX, FY, FR, MODE, USE_HI ) ' PX = INT( FX + 0.5 ) ' PY = INT( FY + 0.5 ) ' PR = INT( FR + 0.5 ) ' PR_SQD = PR ^ 2 ' A_MINUS_ONE = INT( 0.7071 * PR - 0.75 ) ' DSTBASE = 8 AND USE_HI ' IF PR = 4 OR PR = 11 THEN DEC A_MINUS_ONE ' IF MODE = 1 THEN ' FOR NEG_A = -A_MINUS_ONE - 1 TO A_MINUS_ONE ' B = INT( SQR( PR_SQD - NEG_A ^ 2 ) + 0.5 ) ' IF B < PR THEN ' DST = PXL_XADDR( PX - NEG_A ) + PXL_YADDR( PY + B ) + DSTBASE ' POKE DST, PEEK( DST ) OR PXL_MASKS( PX - NEG_A ) ' DST = PXL_XADDR( PX - B ) + PXL_YADDR( PY - NEG_A ) + DSTBASE ' POKE DST, PEEK( DST ) OR PXL_MASKS( PX - B ) ' DST = PXL_XADDR( PX + NEG_A ) + PXL_YADDR( PY - B ) + DSTBASE ' POKE DST, PEEK( DST ) OR PXL_MASKS( PX + NEG_A ) ' DST = PXL_XADDR( PX + B ) + PXL_YADDR( PY + NEG_A ) + DSTBASE ' POKE DST, PEEK( DST ) OR PXL_MASKS( PX + B ) ' ELSE ' CALL PXL_HORZ( PX + NEG_A, PX - NEG_A, PY - B, MODE, USE_HI ) ' CALL PXL_HORZ( PX + NEG_A, PX - NEG_A, PY + B, MODE, USE_HI ) ' DSTBASEL = PXL_XADDR( PX - B ) + DSTBASE ' DSTBASER = PXL_XADDR( PX + B ) + DSTBASE ' MASKL = PXL_MASKS( PX - B ) ' MASKR = PXL_MASKS( PX + B ) ' Y2 = PY - NEG_A ' FOR Y = PY + NEG_A TO Y2 ' POKE DSTBASEL + PXL_YADDR( Y ), PEEK( DSTBASEL + PXL_YADDR( Y ) ) OR MASKL ' POKE DSTBASER + PXL_YADDR( Y ), PEEK( DSTBASER + PXL_YADDR( Y ) ) OR MASKR ' NEXT Y ' NEG_A = -NEG_A ' END IF ' NEXT NEG_A ' B = INT( SQR( PR_SQD - NEG_A ^ 2 ) + 0.5 ) ' IF NEG_A <> B AND PR <> 2 THEN ' DST = PXL_XADDR( PX - NEG_A ) + PXL_YADDR( PY + B ) + DSTBASE ' POKE DST, PEEK( DST ) OR PXL_MASKS( PX - NEG_A ) ' DST = PXL_XADDR( PX - B ) + PXL_YADDR( PY - NEG_A ) + DSTBASE ' POKE DST, PEEK( DST ) OR PXL_MASKS( PX - B ) ' DST = PXL_XADDR( PX + NEG_A ) + PXL_YADDR( PY - B ) + DSTBASE ' POKE DST, PEEK( DST ) OR PXL_MASKS( PX + NEG_A ) ' DST = PXL_XADDR( PX + B ) + PXL_YADDR( PY + NEG_A ) + DSTBASE ' POKE DST, PEEK( DST ) OR PXL_MASKS( PX + B ) ' END IF ' ELSE IF MODE THEN ' FOR NEG_A = -A_MINUS_ONE - 1 TO A_MINUS_ONE ' B = INT( SQR( PR_SQD - NEG_A ^ 2 ) + 0.5 ) ' IF B < PR THEN ' DST = PXL_XADDR( PX - NEG_A ) + PXL_YADDR( PY + B ) + DSTBASE ' POKE DST, PEEK( DST ) XOR PXL_MASKS( PX - NEG_A ) ' DST = PXL_XADDR( PX - B ) + PXL_YADDR( PY - NEG_A ) + DSTBASE ' POKE DST, PEEK( DST ) XOR PXL_MASKS( PX - B ) ' DST = PXL_XADDR( PX + NEG_A ) + PXL_YADDR( PY - B ) + DSTBASE ' POKE DST, PEEK( DST ) XOR PXL_MASKS( PX + NEG_A ) ' DST = PXL_XADDR( PX + B ) + PXL_YADDR( PY + NEG_A ) + DSTBASE ' POKE DST, PEEK( DST ) XOR PXL_MASKS( PX + B ) ' ELSE ' CALL PXL_HORZ( PX + NEG_A, PX - NEG_A, PY - B, MODE, USE_HI ) ' CALL PXL_HORZ( PX + NEG_A, PX - NEG_A, PY + B, MODE, USE_HI ) ' DSTBASEL = PXL_XADDR( PX - B ) + DSTBASE ' DSTBASER = PXL_XADDR( PX + B ) + DSTBASE ' MASKL = PXL_MASKS( PX - B ) ' MASKR = PXL_MASKS( PX + B ) ' Y2 = PY - NEG_A ' FOR Y = PY + NEG_A TO Y2 ' POKE DSTBASEL + PXL_YADDR( Y ), PEEK( DSTBASEL + PXL_YADDR( Y ) ) XOR MASKL ' POKE DSTBASER + PXL_YADDR( Y ), PEEK( DSTBASER + PXL_YADDR( Y ) ) XOR MASKR ' NEXT Y ' NEG_A = -NEG_A ' END IF ' NEXT NEG_A ' B = INT( SQR( PR_SQD - NEG_A ^ 2 ) + 0.5 ) ' IF NEG_A <> B AND PR <> 2 THEN ' DST = PXL_XADDR( PX - NEG_A ) + PXL_YADDR( PY + B ) + DSTBASE ' POKE DST, PEEK( DST ) XOR PXL_MASKS( PX - NEG_A ) ' DST = PXL_XADDR( PX - B ) + PXL_YADDR( PY - NEG_A ) + DSTBASE ' POKE DST, PEEK( DST ) XOR PXL_MASKS( PX - B ) ' DST = PXL_XADDR( PX + NEG_A ) + PXL_YADDR( PY - B ) + DSTBASE ' POKE DST, PEEK( DST ) XOR PXL_MASKS( PX + NEG_A ) ' DST = PXL_XADDR( PX + B ) + PXL_YADDR( PY + NEG_A ) + DSTBASE ' POKE DST, PEEK( DST ) XOR PXL_MASKS( PX + B ) ' END IF ' ELSE ' FOR NEG_A = -A_MINUS_ONE - 1 TO A_MINUS_ONE ' B = INT( SQR( PR_SQD - NEG_A ^ 2 ) + 0.5 ) ' IF B < PR THEN ' DST = PXL_XADDR( PX - NEG_A ) + PXL_YADDR( PY + B ) + DSTBASE ' POKE DST, PEEK( DST ) AND PXL_MASKX( PX - NEG_A ) ' DST = PXL_XADDR( PX - B ) + PXL_YADDR( PY - NEG_A ) + DSTBASE ' POKE DST, PEEK( DST ) AND PXL_MASKX( PX - B ) ' DST = PXL_XADDR( PX + NEG_A ) + PXL_YADDR( PY - B ) + DSTBASE ' POKE DST, PEEK( DST ) AND PXL_MASKX( PX + NEG_A ) ' DST = PXL_XADDR( PX + B ) + PXL_YADDR( PY + NEG_A ) + DSTBASE ' POKE DST, PEEK( DST ) AND PXL_MASKX( PX + B ) ' ELSE ' CALL PXL_HORZ( PX + NEG_A, PX - NEG_A, PY - B, MODE, USE_HI ) ' CALL PXL_HORZ( PX + NEG_A, PX - NEG_A, PY + B, MODE, USE_HI ) ' DSTBASEL = PXL_XADDR( PX - B ) + DSTBASE ' DSTBASER = PXL_XADDR( PX + B ) + DSTBASE ' MASKL = PXL_MASKX( PX - B ) ' MASKR = PXL_MASKX( PX + B ) ' Y2 = PY - NEG_A ' FOR Y = PY + NEG_A TO Y2 ' POKE DSTBASEL + PXL_YADDR( Y ), PEEK( DSTBASEL + PXL_YADDR( Y ) ) AND MASKL ' POKE DSTBASER + PXL_YADDR( Y ), PEEK( DSTBASER + PXL_YADDR( Y ) ) AND MASKR ' NEXT Y ' NEG_A = -NEG_A ' END IF ' NEXT NEG_A ' B = INT( SQR( PR_SQD - NEG_A ^ 2 ) + 0.5 ) ' IF NEG_A <> B AND PR <> 2 THEN ' DST = PXL_XADDR( PX - NEG_A ) + PXL_YADDR( PY + B ) + DSTBASE ' POKE DST, PEEK( DST ) AND PXL_MASKX( PX - NEG_A ) ' DST = PXL_XADDR( PX - B ) + PXL_YADDR( PY - NEG_A ) + DSTBASE ' POKE DST, PEEK( DST ) AND PXL_MASKX( PX - B ) ' DST = PXL_XADDR( PX + NEG_A ) + PXL_YADDR( PY - B ) + DSTBASE ' POKE DST, PEEK( DST ) AND PXL_MASKX( PX + NEG_A ) ' DST = PXL_XADDR( PX + B ) + PXL_YADDR( PY + NEG_A ) + DSTBASE ' POKE DST, PEEK( DST ) AND PXL_MASKX( PX + B ) ' END IF ' END IF ' END SUB ' SUB PXL_CIRCFAST_CLIP( FX, FY, FR, MODE, USE_HI ) ' PX = INT( FX + 0.5 ) ' PY = INT( FY + 0.5 ) ' PR = INT( FR + 0.5 ) ' PR_SQD = PR ^ 2 ' A_MINUS_ONE = INT( 0.7071 * PR - 0.75 ) ' DSTBASE = 8 AND USE_HI ' IF PR = 4 OR PR = 11 THEN DEC A_MINUS_ONE ' IF MODE = 1 THEN ' FOR NEG_A = -A_MINUS_ONE - 1 TO A_MINUS_ONE ' B = INT( SQR( PR_SQD - NEG_A ^ 2 ) + 0.5 ) ' IF B < PR THEN ' X = PX - NEG_A ' Y = PY + B ' IF X >= 0 AND X < PXL_PXHI AND Y >= 0 AND Y < PXL_PYHI THEN ' DST = PXL_XADDR( X ) + PXL_YADDR( Y ) + DSTBASE ' POKE DST, PEEK( DST ) OR PXL_MASKS( X ) ' END IF ' X = PX - B ' Y = PY - NEG_A ' IF X >= 0 AND X < PXL_PXHI AND Y >= 0 AND Y < PXL_PYHI THEN ' DST = PXL_XADDR( X ) + PXL_YADDR( Y ) + DSTBASE ' POKE DST, PEEK( DST ) OR PXL_MASKS( X ) ' END IF ' X = PX + NEG_A ' Y = PY - B ' IF X >= 0 AND X < PXL_PXHI AND Y >= 0 AND Y < PXL_PYHI THEN ' DST = PXL_XADDR( X ) + PXL_YADDR( Y ) + DSTBASE ' POKE DST, PEEK( DST ) OR PXL_MASKS( X ) ' END IF ' X = PX + B ' Y = PY + NEG_A ' IF X >= 0 AND X < PXL_PXHI AND Y >= 0 AND Y < PXL_PYHI THEN ' DST = PXL_XADDR( X ) + PXL_YADDR( Y ) + DSTBASE ' POKE DST, PEEK( DST ) OR PXL_MASKS( X ) ' END IF ' ELSE ' CALL PXL_HORZ_CLIP( PX + NEG_A, PX - NEG_A, PY - B, MODE, USE_HI ) ' CALL PXL_HORZ_CLIP( PX + NEG_A, PX - NEG_A, PY + B, MODE, USE_HI ) ' XL = PX - B ' IF XL >= 0 AND XL < PXL_PXHI THEN USE_XL = TRUE ELSE USE_XL = FALSE ' XR = PX + B ' IF XR >= 0 AND XR < PXL_PXHI THEN USE_XR = TRUE ELSE USE_XR = FALSE ' IF USE_XL THEN DSTBASEL = PXL_XADDR( XL ) + DSTBASE ' IF USE_XR THEN DSTBASER = PXL_XADDR( XR ) + DSTBASE ' IF USE_XL THEN MASKL = PXL_MASKS( XL ) ' IF USE_XR THEN MASKR = PXL_MASKS( XR ) ' Y2 = MIN( PY - NEG_A, PXL_PYHI - 1 ) ' FOR Y = MAX( PY + NEG_A, 0 ) TO Y2 ' IF USE_XL THEN POKE DSTBASEL+PXL_YADDR(Y),PEEK(DSTBASEL+PXL_YADDR(Y)) OR MASKL ' IF USE_XR THEN POKE DSTBASER+PXL_YADDR(Y),PEEK(DSTBASER+PXL_YADDR(Y)) OR MASKR ' NEXT Y ' NEG_A = -NEG_A ' END IF ' NEXT NEG_A ' B = INT( SQR( PR_SQD - NEG_A ^ 2 ) + 0.5 ) ' IF NEG_A <> B AND PR <> 2 THEN ' X = PX - NEG_A ' Y = PY + B ' IF X >= 0 AND X < PXL_PXHI AND Y >= 0 AND Y < PXL_PYHI THEN ' DST = PXL_XADDR( X ) + PXL_YADDR( Y ) + DSTBASE ' POKE DST, PEEK( DST ) OR PXL_MASKS( X ) ' END IF ' X = PX - B ' Y = PY - NEG_A ' IF X >= 0 AND X < PXL_PXHI AND Y >= 0 AND Y < PXL_PYHI THEN ' DST = PXL_XADDR( X ) + PXL_YADDR( Y ) + DSTBASE ' POKE DST, PEEK( DST ) OR PXL_MASKS( X ) ' END IF ' X = PX + NEG_A ' Y = PY - B ' IF X >= 0 AND X < PXL_PXHI AND Y >= 0 AND Y < PXL_PYHI THEN ' DST = PXL_XADDR( X ) + PXL_YADDR( Y ) + DSTBASE ' POKE DST, PEEK( DST ) OR PXL_MASKS( X ) ' END IF ' X = PX + B ' Y = PY + NEG_A ' IF X >= 0 AND X < PXL_PXHI AND Y >= 0 AND Y < PXL_PYHI THEN ' DST = PXL_XADDR( X ) + PXL_YADDR( Y ) + DSTBASE ' POKE DST, PEEK( DST ) OR PXL_MASKS( X ) ' END IF ' END IF ' ELSE IF MODE THEN ' FOR NEG_A = -A_MINUS_ONE - 1 TO A_MINUS_ONE ' B = INT( SQR( PR_SQD - NEG_A ^ 2 ) + 0.5 ) ' IF B < PR THEN ' X = PX - NEG_A ' Y = PY + B ' IF X >= 0 AND X < PXL_PXHI AND Y >= 0 AND Y < PXL_PYHI THEN ' DST = PXL_XADDR( X ) + PXL_YADDR( Y ) + DSTBASE ' POKE DST, PEEK( DST ) XOR PXL_MASKS( X ) ' END IF ' X = PX - B ' Y = PY - NEG_A ' IF X >= 0 AND X < PXL_PXHI AND Y >= 0 AND Y < PXL_PYHI THEN ' DST = PXL_XADDR( X ) + PXL_YADDR( Y ) + DSTBASE ' POKE DST, PEEK( DST ) XOR PXL_MASKS( X ) ' END IF ' X = PX + NEG_A ' Y = PY - B ' IF X >= 0 AND X < PXL_PXHI AND Y >= 0 AND Y < PXL_PYHI THEN ' DST = PXL_XADDR( X ) + PXL_YADDR( Y ) + DSTBASE ' POKE DST, PEEK( DST ) XOR PXL_MASKS( X ) ' END IF ' X = PX + B ' Y = PY + NEG_A ' IF X >= 0 AND X < PXL_PXHI AND Y >= 0 AND Y < PXL_PYHI THEN ' DST = PXL_XADDR( X ) + PXL_YADDR( Y ) + DSTBASE ' POKE DST, PEEK( DST ) XOR PXL_MASKS( X ) ' END IF ' ELSE ' CALL PXL_HORZ_CLIP( PX + NEG_A, PX - NEG_A, PY - B, MODE, USE_HI ) ' CALL PXL_HORZ_CLIP( PX + NEG_A, PX - NEG_A, PY + B, MODE, USE_HI ) ' XL = PX - B ' IF XL >= 0 AND XL < PXL_PXHI THEN USE_XL = TRUE ELSE USE_XL = FALSE ' XR = PX + B ' IF XR >= 0 AND XR < PXL_PXHI THEN USE_XR = TRUE ELSE USE_XR = FALSE ' IF USE_XL THEN DSTBASEL = PXL_XADDR( XL ) + DSTBASE ' IF USE_XR THEN DSTBASER = PXL_XADDR( XR ) + DSTBASE ' IF USE_XL THEN MASKL = PXL_MASKS( XL ) ' IF USE_XR THEN MASKR = PXL_MASKS( XR ) ' Y2 = MIN( PY - NEG_A, PXL_PYHI - 1 ) ' FOR Y = MAX( PY + NEG_A, 0 ) TO Y2 ' IF USE_XL THEN POKE DSTBASEL+PXL_YADDR(Y),PEEK(DSTBASEL+PXL_YADDR(Y)) XOR MASKL ' IF USE_XR THEN POKE DSTBASER+PXL_YADDR(Y),PEEK(DSTBASER+PXL_YADDR(Y)) XOR MASKR ' NEXT Y ' NEG_A = -NEG_A ' END IF ' NEXT NEG_A ' B = INT( SQR( PR_SQD - NEG_A ^ 2 ) + 0.5 ) ' IF NEG_A <> B AND PR <> 2 THEN ' X = PX - NEG_A ' Y = PY + B ' IF X >= 0 AND X < PXL_PXHI AND Y >= 0 AND Y < PXL_PYHI THEN ' DST = PXL_XADDR( X ) + PXL_YADDR( Y ) + DSTBASE ' POKE DST, PEEK( DST ) XOR PXL_MASKS( X ) ' END IF ' X = PX - B ' Y = PY - NEG_A ' IF X >= 0 AND X < PXL_PXHI AND Y >= 0 AND Y < PXL_PYHI THEN ' DST = PXL_XADDR( X ) + PXL_YADDR( Y ) + DSTBASE ' POKE DST, PEEK( DST ) XOR PXL_MASKS( X ) ' END IF ' X = PX + NEG_A ' Y = PY - B ' IF X >= 0 AND X < PXL_PXHI AND Y >= 0 AND Y < PXL_PYHI THEN ' DST = PXL_XADDR( X ) + PXL_YADDR( Y ) + DSTBASE ' POKE DST, PEEK( DST ) XOR PXL_MASKS( X ) ' END IF ' X = PX + B ' Y = PY + NEG_A ' IF X >= 0 AND X < PXL_PXHI AND Y >= 0 AND Y < PXL_PYHI THEN ' DST = PXL_XADDR( X ) + PXL_YADDR( Y ) + DSTBASE ' POKE DST, PEEK( DST ) XOR PXL_MASKS( X ) ' END IF ' END IF ' ELSE ' FOR NEG_A = -A_MINUS_ONE - 1 TO A_MINUS_ONE ' B = INT( SQR( PR_SQD - NEG_A ^ 2 ) + 0.5 ) ' IF B < PR THEN ' X = PX - NEG_A ' Y = PY + B ' IF X >= 0 AND X < PXL_PXHI AND Y >= 0 AND Y < PXL_PYHI THEN ' DST = PXL_XADDR( X ) + PXL_YADDR( Y ) + DSTBASE ' POKE DST, PEEK( DST ) AND PXL_MASKX( X ) ' END IF ' X = PX - B ' Y = PY - NEG_A ' IF X >= 0 AND X < PXL_PXHI AND Y >= 0 AND Y < PXL_PYHI THEN ' DST = PXL_XADDR( X ) + PXL_YADDR( Y ) + DSTBASE ' POKE DST, PEEK( DST ) AND PXL_MASKX( X ) ' END IF ' X = PX + NEG_A ' Y = PY - B ' IF X >= 0 AND X < PXL_PXHI AND Y >= 0 AND Y < PXL_PYHI THEN ' DST = PXL_XADDR( X ) + PXL_YADDR( Y ) + DSTBASE ' POKE DST, PEEK( DST ) AND PXL_MASKX( X ) ' END IF ' X = PX + B ' Y = PY + NEG_A ' IF X >= 0 AND X < PXL_PXHI AND Y >= 0 AND Y < PXL_PYHI THEN ' DST = PXL_XADDR( X ) + PXL_YADDR( Y ) + DSTBASE ' POKE DST, PEEK( DST ) AND PXL_MASKX( X ) ' END IF ' ELSE ' CALL PXL_HORZ_CLIP( PX + NEG_A, PX - NEG_A, PY - B, MODE, USE_HI ) ' CALL PXL_HORZ_CLIP( PX + NEG_A, PX - NEG_A, PY + B, MODE, USE_HI ) ' XL = PX - B ' IF XL >= 0 AND XL < PXL_PXHI THEN USE_XL = TRUE ELSE USE_XL = FALSE ' XR = PX + B ' IF XR >= 0 AND XR < PXL_PXHI THEN USE_XR = TRUE ELSE USE_XR = FALSE ' IF USE_XL THEN DSTBASEL = PXL_XADDR( XL ) + DSTBASE ' IF USE_XR THEN DSTBASER = PXL_XADDR( XR ) + DSTBASE ' IF USE_XL THEN MASKL = PXL_MASKX( XL ) ' IF USE_XR THEN MASKR = PXL_MASKX( XR ) ' Y2 = MIN( PY - NEG_A, PXL_PYHI - 1 ) ' FOR Y = MAX( PY + NEG_A, 0 ) TO Y2 ' IF USE_XL THEN POKE DSTBASEL+PXL_YADDR(Y),PEEK(DSTBASEL+PXL_YADDR(Y)) AND MASKL ' IF USE_XR THEN POKE DSTBASER+PXL_YADDR(Y),PEEK(DSTBASER+PXL_YADDR(Y)) AND MASKR ' NEXT Y ' NEG_A = -NEG_A ' END IF ' NEXT NEG_A ' B = INT( SQR( PR_SQD - NEG_A ^ 2 ) + 0.5 ) ' IF NEG_A <> B AND PR <> 2 THEN ' X = PX - NEG_A ' Y = PY + B ' IF X >= 0 AND X < PXL_PXHI AND Y >= 0 AND Y < PXL_PYHI THEN ' DST = PXL_XADDR( X ) + PXL_YADDR( Y ) + DSTBASE ' POKE DST, PEEK( DST ) AND PXL_MASKX( X ) ' END IF ' X = PX - B ' Y = PY - NEG_A ' IF X >= 0 AND X < PXL_PXHI AND Y >= 0 AND Y < PXL_PYHI THEN ' DST = PXL_XADDR( X ) + PXL_YADDR( Y ) + DSTBASE ' POKE DST, PEEK( DST ) AND PXL_MASKX( X ) ' END IF ' X = PX + NEG_A ' Y = PY - B ' IF X >= 0 AND X < PXL_PXHI AND Y >= 0 AND Y < PXL_PYHI THEN ' DST = PXL_XADDR( X ) + PXL_YADDR( Y ) + DSTBASE ' POKE DST, PEEK( DST ) AND PXL_MASKX( X ) ' END IF ' X = PX + B ' Y = PY + NEG_A ' IF X >= 0 AND X < PXL_PXHI AND Y >= 0 AND Y < PXL_PYHI THEN ' DST = PXL_XADDR( X ) + PXL_YADDR( Y ) + DSTBASE ' POKE DST, PEEK( DST ) AND PXL_MASKX( X ) ' END IF ' END IF ' END IF ' END SUB SUB PXL_CIRCFILL( FX, FY, FR, MODE, USE_HI ) PX = INT( FX + 0.5 ) PY = INT( FY + 0.5 ) PR = INT( FR + 0.5 ) IF PR <> 1 THEN PR_SQD = PR ^ 2 A_MINUS_ONE = INT( 0.7071 * PR - 0.75 ) IF PR = 4 OR PR = 11 THEN DEC A_MINUS_ONE OLD_B = 0.1 FOR NEG_A = -A_MINUS_ONE - 1 TO A_MINUS_ONE B = INT( SQR( PR_SQD - NEG_A ^ 2 ) + 0.5 ) IF B < PR THEN IF B <> -NEG_A THEN CALL PXL_HORZ( PX - B, PX + B, PY + NEG_A, MODE, USE_HI ) IF B <> OLD_B AND OLD_B <> 0.9 THEN OLD_B = B CALL PXL_HORZ( PX + NEG_A, PX - NEG_A, PY - B, MODE, USE_HI ) CALL PXL_HORZ( PX + NEG_A, PX - NEG_A, PY + B, MODE, USE_HI ) END IF ELSE OLD_B = 0.9 CALL PXL_RECT( PX - B, PY + NEG_A, PX + B, PY - NEG_A, MODE, USE_HI ) CALL PXL_HORZ( PX + NEG_A, PX - NEG_A, PY - B, MODE, USE_HI ) CALL PXL_HORZ( PX + NEG_A, PX - NEG_A, PY + B, MODE, USE_HI ) NEG_A = -NEG_A END IF NEXT NEG_A B = INT( SQR( PR_SQD - NEG_A ^ 2 ) + 0.5 ) IF B <> NEG_A THEN CALL PXL_HORZ( PX - B, PX + B, PY + NEG_A, MODE, USE_HI ) ELSE CALL PXL_HORZ( PX - 1, PX + 1, PY, MODE, USE_HI ) CALL PXL_SETP( PX, PY - 1, MODE, USE_HI ) CALL PXL_SETP( PX, PY + 1, MODE, USE_HI ) END IF END SUB SUB PXL_CIRCFILL_CLIP( FX, FY, FR, MODE, USE_HI ) PX = INT( FX + 0.5 ) PY = INT( FY + 0.5 ) PR = INT( FR + 0.5 ) IF PR <> 1 THEN PR_SQD = PR ^ 2 A_MINUS_ONE = INT( 0.7071 * PR - 0.75 ) IF PR = 4 OR PR = 11 THEN DEC A_MINUS_ONE OLD_B = 0.1 FOR NEG_A = -A_MINUS_ONE - 1 TO A_MINUS_ONE B = INT( SQR( PR_SQD - NEG_A ^ 2 ) + 0.5 ) IF B < PR THEN IF B <> -NEG_A THEN CALL PXL_HORZ_CLIP( PX - B, PX + B, PY + NEG_A, MODE, USE_HI ) IF B <> OLD_B AND OLD_B <> 0.9 THEN OLD_B = B CALL PXL_HORZ_CLIP( PX + NEG_A, PX - NEG_A, PY - B, MODE, USE_HI ) CALL PXL_HORZ_CLIP( PX + NEG_A, PX - NEG_A, PY + B, MODE, USE_HI ) END IF ELSE OLD_B = 0.9 CALL PXL_RECT_CLIP( PX - B, PY + NEG_A, PX + B, PY - NEG_A, MODE, USE_HI ) CALL PXL_HORZ_CLIP( PX + NEG_A, PX - NEG_A, PY - B, MODE, USE_HI ) CALL PXL_HORZ_CLIP( PX + NEG_A, PX - NEG_A, PY + B, MODE, USE_HI ) NEG_A = -NEG_A END IF NEXT NEG_A B = INT( SQR( PR_SQD - NEG_A ^ 2 ) + 0.5 ) IF B <> NEG_A THEN CALL PXL_HORZ( PX - B, PX + B, PY + NEG_A, MODE, USE_HI ) ELSE CALL PXL_HORZ_CLIP( PX - 1, PX + 1, PY, MODE, USE_HI ) CALL PXL_SETP_CLIP( PX, PY - 1, MODE, USE_HI ) CALL PXL_SETP_CLIP( PX, PY + 1, MODE, USE_HI ) END IF END SUB SUB PXL_LINE( FX1, FY1, FX2, FY2, MODE, USE_HI ) IF FX2 = FX1 THEN IS_STEEP = TRUE ELSE IS_STEEP = ABS( (FY2-FY1) / (FX2-FX1) ) >= 1.0 ADD_HI = 8 AND USE_HI IF IS_STEEP THEN IF FY1 <= FY2 THEN FX = FX1 + 0.5 PY = INT( FY1 + 0.5 ) FX_HI = FX2 + 0.5 PY_HI = INT( FY2 + 0.5 ) ELSE FX = FX2 + 0.5 PY = INT( FY2 + 0.5 ) FX_HI = FX1 + 0.5 PY_HI = INT( FY1 + 0.5 ) END IF IF PY = PY_HI THEN FX_STEP = 0.0 ELSE FX_STEP = (FX_HI-FX) / (PY_HI-PY) IF MODE = 1 THEN FOR PY = PY TO PY_HI ADDR = PXL_XADDR( FX ) + PXL_YADDR( PY ) + ADD_HI POKE ADDR, PEEK( ADDR ) OR PXL_MASKS( FX ) ADD FX, FX_STEP NEXT PY ELSE IF MODE THEN FOR PY = PY TO PY_HI ADDR = PXL_XADDR( FX ) + PXL_YADDR( PY ) + ADD_HI POKE ADDR, PEEK( ADDR ) XOR PXL_MASKS( FX ) ADD FX, FX_STEP NEXT PY ELSE FOR PY = PY TO PY_HI ADDR = PXL_XADDR( FX ) + PXL_YADDR( PY ) + ADD_HI POKE ADDR, PEEK( ADDR ) AND PXL_MASKX( FX ) ADD FX, FX_STEP NEXT PY END IF ELSE IF FX1 <= FX2 THEN PX = INT( FX1 + 0.5 ) FY = FY1 + 0.5 PX_HI = INT( FX2 + 0.5 ) FY_HI = FY2 + 0.5 ELSE PX = INT( FX2 + 0.5 ) FY = FY2 + 0.5 PX_HI = INT( FX1 + 0.5 ) FY_HI = FY1 + 0.5 END IF FY_STEP = (FY_HI-FY) / (PX_HI-PX) IF MODE = 1 THEN FOR PX = PX TO PX_HI ADDR = PXL_XADDR( PX ) + PXL_YADDR( FY ) + ADD_HI POKE ADDR, PEEK( ADDR ) OR PXL_MASKS( PX ) ADD FY, FY_STEP NEXT PX ELSE IF MODE THEN FOR PX = PX TO PX_HI ADDR = PXL_XADDR( PX ) + PXL_YADDR( FY ) + ADD_HI POKE ADDR, PEEK( ADDR ) XOR PXL_MASKS( PX ) ADD FY, FY_STEP NEXT PX ELSE FOR PX = PX TO PX_HI ADDR = PXL_XADDR( PX ) + PXL_YADDR( FY ) + ADD_HI POKE ADDR, PEEK( ADDR ) AND PXL_MASKX( PX ) ADD FY, FY_STEP NEXT PX END IF END IF END SUB SUB PXL_LINE_CLIP( FX1, FY1, FX2, FY2, MODE, USE_HI ) X1 = FX1 Y1 = FY1 X2 = FX2 Y2 = FY2 IS_NOT_VERT = X1 <> X2 IF IS_NOT_VERT THEN M = ( Y2 - Y1 ) / ( X2 - X1 ) B = Y1 - M * X1 END IF IF X1 > X2 THEN SWAP X1, X2 SWAP Y1, Y2 END IF IF X1 < -0.5 THEN IF X2 < -0.5 THEN EXIT SUB X1 = -0.5 Y1 = M * -0.5 + B END IF IF X2 >= 159.5 THEN IF X1 >= 159.5 THEN EXIT SUB X2 = 159.5 Y2 = M * 159.5 + B END IF IF Y1 > Y2 THEN SWAP X1, X2 SWAP Y1, Y2 END IF IF Y1 < -0.5 THEN IF Y2 < -0.5 THEN EXIT SUB IF IS_NOT_VERT THEN X1 = ( -0.5 - B ) / M Y1 = -0.5 END IF IF Y2 >= 127.5 THEN IF Y1 >= 127.5 THEN EXIT SUB IF IS_NOT_VERT THEN X2 = ( 127.5 - B ) / M Y2 = 127.5 END IF CALL PXL_LINE( X1, Y1, X2, Y2, MODE, USE_HI ) END SUB SUB PXL_RECT( FX1, FY1, FX2, FY2, MODE, USE_HI ) PX = FX1 + 0.5 AND %11111000 PX_HI = ( FX2 + 0.5 AND %11111000 ) - 8 PY_LO = INT( FY1 + 0.5 ) PY_HI = INT( FY2 + 0.5 ) IF PX = PX_HI + 8 THEN MASK1 = PXL_MASKR( FX1 + 0.5 ) AND PXL_MASKL( FX2 + 0.5 ) USE_MASK2 = FALSE ELSE MASK1 = PXL_MASKR( FX1 + 0.5 ) USE_MASK2 = TRUE MASK2 = PXL_MASKL( FX2 + 0.5 ) END IF ADD_HI = 8 AND USE_HI ADDR = PXL_XADDR( PX ) + ADD_HI IF MODE = 1 THEN FOR PY = PY_LO TO PY_HI POKE ADDR + PXL_YADDR( PY ), PEEK( ADDR + PXL_YADDR( PY ) ) OR MASK1 NEXT PY FOR PX = PX + 8 TO PX_HI STEP 8 ADDR = PXL_XADDR( PX ) + ADD_HI FOR PY = PY_LO TO PY_HI POKE ADDR + PXL_YADDR( PY ), $FF NEXT PY NEXT PX IF USE_MASK2 THEN ADDR = PXL_XADDR( PX ) + ADD_HI FOR PY = PY_LO TO PY_HI POKE ADDR + PXL_YADDR( PY ), PEEK( ADDR + PXL_YADDR( PY ) ) OR MASK2 NEXT PY END IF ELSE IF MODE THEN FOR PY = PY_LO TO PY_HI POKE ADDR + PXL_YADDR( PY ), PEEK( ADDR + PXL_YADDR( PY ) ) XOR MASK1 NEXT PY FOR PX = PX + 8 TO PX_HI STEP 8 ADDR = PXL_XADDR( PX ) + ADD_HI FOR PY = PY_LO TO PY_HI POKE ADDR + PXL_YADDR( PY ), NOT PEEK( ADDR + PXL_YADDR( PY ) ) NEXT PY NEXT PX IF USE_MASK2 THEN ADDR = PXL_XADDR( PX ) + ADD_HI FOR PY = PY_LO TO PY_HI POKE ADDR + PXL_YADDR( PY ), PEEK( ADDR + PXL_YADDR( PY ) ) XOR MASK2 NEXT PY END IF ELSE MASK1 = NOT MASK1 FOR PY = PY_LO TO PY_HI POKE ADDR + PXL_YADDR( PY ), PEEK( ADDR + PXL_YADDR( PY ) ) AND MASK1 NEXT PY FOR PX = PX + 8 TO PX_HI STEP 8 ADDR = PXL_XADDR( PX ) + ADD_HI FOR PY = PY_LO TO PY_HI POKE ADDR + PXL_YADDR( PY ), 0 NEXT PY NEXT PX IF USE_MASK2 THEN MASK2 = NOT MASK2 ADDR = PXL_XADDR( PX ) + ADD_HI FOR PY = PY_LO TO PY_HI POKE ADDR + PXL_YADDR( PY ), PEEK( ADDR + PXL_YADDR( PY ) ) AND MASK2 NEXT PY END IF END IF END SUB SUB PXL_RECT_CLIP( FX1, FY1, FX2, FY2, MODE, USE_HI ) IF FX2 < 0 OR FX1 >= PXL_FXHI OR FY2 < 0 OR FY1 >= PXL_FYHI THEN EXIT SUB CALL PXL_RECT(MAX(FX1,0),MAX(FY1,0),MIN(FX2,PXL_PXHI-1),MIN(FY2,PXL_PYHI-1),MODE,USE_HI) END SUB SUB PXL_TRIFAST( FX1, FY1, FX2, FY2, FX3, FY3, MODE, USE_HI ) 'FAST MEANS IT LACKS PIXEL-PERFECT OVERLAP VS (3) CALLS TO PXL_LINE IF Y1 <= Y2 THEN X1 = FX1 PY1 = INT( FY1 + 0.5 ) X2 = FX2 PY2 = INT( FY2 + 0.5 ) X3 = FX3 PY3 = INT( FY3 + 0.5 ) ELSE X1 = FX2 PY1 = INT( FY2 + 0.5 ) X2 = FX1 PY2 = INT( FY1 + 0.5 ) X3 = FX3 PY3 = INT( FY3 + 0.5 ) END IF IF PY3 < PY2 THEN SWAP X2, X3 SWAP PY2, PY3 IF PY2 < PY1 THEN SWAP X1, X2 SWAP PY1, PY2 END IF END IF IF PY1 = PY2 THEN IF PY2 = PY3 THEN CALL PXL_HORZ( MIN(MIN(X1,X2),X3), MAX(MAX(X1,X2),X3), PY1, MODE, USE_HI) ELSE X_STEP13 = ( X3 - X1 ) / ( PY3 - PY1 ) X_STEP23 = ( X3 - X2 ) / ( PY3 - PY2 ) IF X1 <= X2 THEN CALL PXL_HORZ( X1, X2, PY1, MODE, USE_HI ) FOR PY1 = PY1 + 1 TO PY3 ADD X1, X_STEP13 ADD X2, X_STEP23 CALL PXL_HORZ( X1, X2, PY1, MODE, USE_HI ) NEXT PY1 ELSE CALL PXL_HORZ( X2, X1, PY1, MODE, USE_HI ) FOR PY1 = PY1 + 1 TO PY3 ADD X2, X_STEP23 ADD X1, X_STEP13 CALL PXL_HORZ( X2, X1, PY1, MODE, USE_HI ) NEXT PY1 END IF END IF ELSE X_STEP12 = ( X2 - X1 ) / ( PY2 - PY1 ) X_STEP13 = ( X3 - X1 ) / ( PY3 - PY1 ) IF PY2 = PY3 THEN X_STEP23 = 0 ELSE X_STEP23 = ( X3 - X2 ) / ( PY3 - PY2 ) XR = X1 CALL PXL_HORZ( X1, XR, PY1, MODE, USE_HI ) IF X_STEP12 <= X_STEP13 THEN FOR PY1 = PY1 + 1 TO PY2 ADD X1, X_STEP12 ADD XR, X_STEP13 CALL PXL_HORZ( X1, XR, PY1, MODE, USE_HI ) NEXT PY1 FOR PY1 = PY1 TO PY3 ADD X1, X_STEP23 ADD XR, X_STEP13 CALL PXL_HORZ( X1, XR, PY1, MODE, USE_HI ) NEXT PY1 ELSE FOR PY1 = PY1 + 1 TO PY2 ADD X1, X_STEP13 ADD XR, X_STEP12 CALL PXL_HORZ( X1, XR, PY1, MODE, USE_HI ) NEXT PY1 FOR PY1 = PY1 TO PY3 ADD X1, X_STEP13 ADD XR, X_STEP23 CALL PXL_HORZ( X1, XR, PY1, MODE, USE_HI ) NEXT PY1 END IF END IF END SUB SUB PXL_TRIFAST_CLIP( FX1, FY1, FX2, FY2, FX3, FY3, MODE, USE_HI ) 'FAST MEANS IT LACKS PIXEL-PERFECT OVERLAP VS (3) CALLS TO PXL_LINE IF Y1 <= Y2 THEN X1 = FX1 PY1 = INT( FY1 + 0.5 ) X2 = FX2 PY2 = INT( FY2 + 0.5 ) X3 = FX3 PY3 = INT( FY3 + 0.5 ) ELSE X1 = FX2 PY1 = INT( FY2 + 0.5 ) X2 = FX1 PY2 = INT( FY1 + 0.5 ) X3 = FX3 PY3 = INT( FY3 + 0.5 ) END IF IF PY3 < PY2 THEN SWAP X2, X3 SWAP PY2, PY3 IF PY2 < PY1 THEN SWAP X1, X2 SWAP PY1, PY2 END IF END IF IF PY1 = PY2 THEN IF PY2 = PY3 THEN CALL PXL_HORZ_CLIP( MIN(MIN(X1,X2),X3), MAX(MAX(X1,X2),X3), PY1, MODE, USE_HI) ELSE X_STEP13 = ( X3 - X1 ) / ( PY3 - PY1 ) X_STEP23 = ( X3 - X2 ) / ( PY3 - PY2 ) IF X1 <= X2 THEN CALL PXL_HORZ_CLIP( X1, X2, PY1, MODE, USE_HI ) FOR PY1 = PY1 + 1 TO PY3 ADD X1, X_STEP13 ADD X2, X_STEP23 CALL PXL_HORZ_CLIP( X1, X2, PY1, MODE, USE_HI ) NEXT PY1 ELSE CALL PXL_HORZ_CLIP( X2, X1, PY1, MODE, USE_HI ) FOR PY1 = PY1 + 1 TO PY3 ADD X2, X_STEP23 ADD X1, X_STEP13 CALL PXL_HORZ_CLIP( X2, X1, PY1, MODE, USE_HI ) NEXT PY1 END IF END IF ELSE X_STEP12 = ( X2 - X1 ) / ( PY2 - PY1 ) X_STEP13 = ( X3 - X1 ) / ( PY3 - PY1 ) IF PY2 = PY3 THEN X_STEP23 = 0 ELSE X_STEP23 = ( X3 - X2 ) / ( PY3 - PY2 ) XR = X1 CALL PXL_HORZ_CLIP( X1, XR, PY1, MODE, USE_HI ) IF X_STEP12 <= X_STEP13 THEN FOR PY1 = PY1 + 1 TO PY2 ADD X1, X_STEP12 ADD XR, X_STEP13 CALL PXL_HORZ_CLIP( X1, XR, PY1, MODE, USE_HI ) NEXT PY1 FOR PY1 = PY1 TO PY3 ADD X1, X_STEP23 ADD XR, X_STEP13 CALL PXL_HORZ_CLIP( X1, XR, PY1, MODE, USE_HI ) NEXT PY1 ELSE FOR PY1 = PY1 + 1 TO PY2 ADD X1, X_STEP13 ADD XR, X_STEP12 CALL PXL_HORZ_CLIP( X1, XR, PY1, MODE, USE_HI ) NEXT PY1 FOR PY1 = PY1 TO PY3 ADD X1, X_STEP13 ADD XR, X_STEP23 CALL PXL_HORZ_CLIP( X1, XR, PY1, MODE, USE_HI ) NEXT PY1 END IF END IF END SUB SUB PXL_TESSFAST( FX1, FY1, FX2, FY2, FX3, FY3, MODE, USE_HI ) 'FAST MEANS IT LACKS PIXEL-PERFECT OVERLAP VS (3) CALLS TO PXL_LINE IF Y1 <= Y2 THEN X1 = FX1 PY1 = INT( FY1 + 0.5 ) X2 = FX2 PY2 = INT( FY2 + 0.5 ) X3 = FX3 PY3 = INT( FY3 + 0.5 ) ELSE X1 = FX2 PY1 = INT( FY2 + 0.5 ) X2 = FX1 PY2 = INT( FY1 + 0.5 ) X3 = FX3 PY3 = INT( FY3 + 0.5 ) END IF IF PY3 < PY2 THEN SWAP X2, X3 SWAP PY2, PY3 IF PY2 < PY1 THEN SWAP X1, X2 SWAP PY1, PY2 END IF END IF IF PY1 = PY2 THEN IF PY2 = PY3 THEN CALL PXL_HORZ( MIN(MIN(X1,X2),X3), MAX(MAX(X1,X2),X3), PY1, MODE, USE_HI ) ELSE X_STEP13 = ( X3 - X1 ) / ( PY3 - PY1 ) X_STEP23 = ( X3 - X2 ) / ( PY3 - PY2 ) IF X1 <= X2 THEN DEC X2 IF INT( X1 ) <= INT( X2 ) THEN CALL PXL_HORZ( X1, X2, PY1, MODE, USE_HI ) FOR PY1 = PY1 + 1 TO PY3 ADD X1, X_STEP13 ADD X2, X_STEP23 IF INT( X1 ) <= INT( X2 ) THEN CALL PXL_HORZ( X1, X2, PY1, MODE, USE_HI ) NEXT PY1 ELSE DEC X1 IF INT( X2 ) <= INT( X1 ) THEN CALL PXL_HORZ( X2, X1, PY1, MODE, USE_HI ) FOR PY1 = PY1 + 1 TO PY3 ADD X2, X_STEP23 ADD X1, X_STEP13 IF INT( X2 ) <= INT( X1 ) THEN CALL PXL_HORZ( X2, X1, PY1, MODE, USE_HI ) NEXT PY1 END IF END IF ELSE X_STEP12 = ( X2 - X1 ) / ( PY2 - PY1 ) X_STEP13 = ( X3 - X1 ) / ( PY3 - PY1 ) IF PY2 = PY3 THEN X_STEP23 = 0 ELSE X_STEP23 = ( X3 - X2 ) / ( PY3 - PY2 ) XR = X1 - 1 IF INT( X1 ) <= INT( XR ) THEN CALL PXL_HORZ( X1, XR, PY1, MODE, USE_HI ) IF X_STEP12 <= X_STEP13 THEN FOR PY1 = PY1 + 1 TO PY2 ADD X1, X_STEP12 ADD XR, X_STEP13 IF INT( X1 ) <= INT( XR ) THEN CALL PXL_HORZ( X1, XR, PY1, MODE, USE_HI ) NEXT PY1 FOR PY1 = PY1 TO PY3 ADD X1, X_STEP23 ADD XR, X_STEP13 IF INT( X1 ) <= INT( XR ) THEN CALL PXL_HORZ( X1, XR, PY1, MODE, USE_HI ) NEXT PY1 ELSE FOR PY1 = PY1 + 1 TO PY2 ADD X1, X_STEP13 ADD XR, X_STEP12 IF INT( X1 ) <= INT( XR ) THEN CALL PXL_HORZ( X1, XR, PY1, MODE, USE_HI ) NEXT PY1 FOR PY1 = PY1 TO PY3 ADD X1, X_STEP13 ADD XR, X_STEP23 IF INT( X1 ) <= INT( XR ) THEN CALL PXL_HORZ( X1, XR, PY1, MODE, USE_HI ) NEXT PY1 END IF END IF END SUB SUB PXL_TESSFAST_CLIP( FX1, FY1, FX2, FY2, FX3, FY3, MODE, USE_HI ) 'FAST MEANS IT LACKS PIXEL-PERFECT OVERLAP VS (3) CALLS TO PXL_LINE IF Y1 <= Y2 THEN X1 = FX1 PY1 = INT( FY1 + 0.5 ) X2 = FX2 PY2 = INT( FY2 + 0.5 ) X3 = FX3 PY3 = INT( FY3 + 0.5 ) ELSE X1 = FX2 PY1 = INT( FY2 + 0.5 ) X2 = FX1 PY2 = INT( FY1 + 0.5 ) X3 = FX3 PY3 = INT( FY3 + 0.5 ) END IF IF PY3 < PY2 THEN SWAP X2, X3 SWAP PY2, PY3 IF PY2 < PY1 THEN SWAP X1, X2 SWAP PY1, PY2 END IF END IF IF PY1 = PY2 THEN IF PY2 = PY3 THEN CALL PXL_HORZ_CLIP( MIN(MIN(X1,X2),X3), MAX(MAX(X1,X2),X3), PY1, MODE, USE_HI ) ELSE X_STEP13 = ( X3 - X1 ) / ( PY3 - PY1 ) X_STEP23 = ( X3 - X2 ) / ( PY3 - PY2 ) IF X1 <= X2 THEN DEC X2 IF INT( X1 ) <= INT( X2 ) THEN CALL PXL_HORZ_CLIP( X1, X2, PY1, MODE, USE_HI ) FOR PY1 = PY1 + 1 TO PY3 ADD X1, X_STEP13 ADD X2, X_STEP23 IF INT( X1 ) <= INT( X2 ) THEN CALL PXL_HORZ_CLIP( X1, X2, PY1, MODE, USE_HI ) NEXT PY1 ELSE DEC X1 IF INT( X2 ) <= INT( X1 ) THEN CALL PXL_HORZ_CLIP( X2, X1, PY1, MODE, USE_HI ) FOR PY1 = PY1 + 1 TO PY3 ADD X2, X_STEP23 ADD X1, X_STEP13 IF INT( X2 ) <= INT( X1 ) THEN CALL PXL_HORZ_CLIP( X2, X1, PY1, MODE, USE_HI ) NEXT PY1 END IF END IF ELSE X_STEP12 = ( X2 - X1 ) / ( PY2 - PY1 ) X_STEP13 = ( X3 - X1 ) / ( PY3 - PY1 ) IF PY2 = PY3 THEN X_STEP23 = 0 ELSE X_STEP23 = ( X3 - X2 ) / ( PY3 - PY2 ) XR = X1 - 1 IF INT( X1 ) <= INT( XR ) THEN CALL PXL_HORZ_CLIP( X1, XR, PY1, MODE, USE_HI ) IF X_STEP12 <= X_STEP13 THEN FOR PY1 = PY1 + 1 TO PY2 ADD X1, X_STEP12 ADD XR, X_STEP13 IF INT( X1 ) <= INT( XR ) THEN CALL PXL_HORZ_CLIP( X1, XR, PY1, MODE, USE_HI ) NEXT PY1 FOR PY1 = PY1 TO PY3 ADD X1, X_STEP23 ADD XR, X_STEP13 IF INT( X1 ) <= INT( XR ) THEN CALL PXL_HORZ_CLIP( X1, XR, PY1, MODE, USE_HI ) NEXT PY1 ELSE FOR PY1 = PY1 + 1 TO PY2 ADD X1, X_STEP13 ADD XR, X_STEP12 IF INT( X1 ) <= INT( XR ) THEN CALL PXL_HORZ_CLIP( X1, XR, PY1, MODE, USE_HI ) NEXT PY1 FOR PY1 = PY1 TO PY3 ADD X1, X_STEP13 ADD XR, X_STEP23 IF INT( X1 ) <= INT( XR ) THEN CALL PXL_HORZ_CLIP( X1, XR, PY1, MODE, USE_HI ) NEXT PY1 END IF END IF END SUB SUB PXL_CELL( PX, PY, C, MODE, USE_HI, USE_INV ) Y2 = MIN( ( PY AND $7E ) + 7, PXL_PYHI - 1 ) DSTBASE = PXL_XADDR( PX ) + ( 8 AND USE_HI ) SRC = PXL_SPRITEADDR + 16 * C IF MODE = 1 THEN FOR Y = PY AND $7E TO Y2 STEP 2 DST = DSTBASE + PXL_YADDR( Y ) POKEW DST, PEEKW( DST ) OR PEEKW( SRC ) XOR USE_INV ADD SRC, 2 NEXT Y ELSE IF MODE = 2 THEN FOR Y = PY AND $7E TO Y2 STEP 2 POKEW DSTBASE + PXL_YADDR( Y ), PEEKW( SRC ) XOR USE_INV ADD SRC, 2 NEXT Y ELSE IF MODE THEN FOR Y = PY AND $7E TO Y2 STEP 2 DST = DSTBASE + PXL_YADDR( Y ) POKEW DST, PEEKW( DST ) XOR PEEKW( SRC ) XOR USE_INV ADD SRC, 2 NEXT Y ELSE FOR Y = PY AND $7E TO Y2 STEP 2 DST = DSTBASE + PXL_YADDR( Y ) POKEW DST, PEEKW( DST ) AND PEEKW( SRC ) XOR USE_INV ADD SRC, 2 NEXT Y END IF END SUB SUB PXL_SPRITE( PX, PY, C, MODE, USE_HI, USE_INV ) Y2 = MIN( PY + 7, PXL_PYHI - 1 ) DSTBASE = PXL_XADDR( PX ) + ( 8 AND USE_HI ) SRC1 = PXL_SPRITEADDR + 16 * C SRC2 = SRC1 COL = PX MOD 8 BITSHIFT = 2 ^ COL IF MODE = 1 THEN FOR Y = PY TO Y2 DST = DSTBASE + PXL_YADDR( Y ) POKE DST, PEEK(DST) OR (PEEK(SRC1) XOR $FF AND USE_INV)\BITSHIFT INC SRC1 NEXT Y IF COL AND PX + 8 < PXL_PXHI THEN DSTBASE=PXL_XADDR(PX+8)+(8 AND USE_HI) BITSHIFT = 2 ^ ( 8 - COL ) FOR Y = PY TO Y2 DST = DSTBASE + PXL_YADDR( Y ) POKE DST, PEEK(DST) OR (PEEK(SRC2) XOR USE_INV)*BITSHIFT INC SRC2 NEXT Y END IF ELSE IF MODE = 2 THEN FOR Y = PY TO Y2 DST = DSTBASE + PXL_YADDR( Y ) POKE DST, PEEK(DST) AND PXL_MASKW(PX) OR (PEEK(SRC1) XOR $FF AND USE_INV)\BITSHIFT INC SRC1 NEXT Y IF COL AND PX + 8 < PXL_PXHI THEN DSTBASE=PXL_XADDR(PX+8)+(8 AND USE_HI) BITSHIFT = 2 ^ ( 8 - COL ) FOR Y = PY TO Y2 DST = DSTBASE + PXL_YADDR( Y ) POKE DST, PEEK(DST) AND PXL_MASKR(PX) OR (PEEK(SRC2) XOR USE_INV)*BITSHIFT INC SRC2 NEXT Y END IF ELSE IF MODE THEN FOR Y = PY TO Y2 DST = DSTBASE + PXL_YADDR( Y ) POKE DST, PEEK(DST) XOR (PEEK(SRC1) XOR $FF AND USE_INV)\BITSHIFT INC SRC1 NEXT Y IF COL AND PX + 8 < PXL_PXHI THEN DSTBASE=PXL_XADDR(PX+8)+(8 AND USE_HI) BITSHIFT = 2 ^ ( 8 - COL ) FOR Y = PY TO Y2 DST = DSTBASE + PXL_YADDR( Y ) POKE DST, PEEK(DST) XOR (PEEK(SRC2) XOR USE_INV)*BITSHIFT INC SRC2 NEXT Y END IF ELSE FOR Y = PY TO Y2 DST = DSTBASE + PXL_YADDR( Y ) POKE DST, PEEK(DST) AND (PXL_MASKW(PX) OR (PEEK(SRC1) XOR $FF AND USE_INV)\BITSHIFT) INC SRC1 NEXT Y IF COL AND PX + 8 < PXL_PXHI THEN DSTBASE=PXL_XADDR(PX+8)+(8 AND USE_HI) BITSHIFT = 2 ^ ( 8 - COL ) FOR Y = PY TO Y2 DST = DSTBASE + PXL_YADDR( Y ) POKE DST, PEEK(DST) AND (PXL_MASKR(PX) OR (PEEK(SRC2) XOR USE_INV)*BITSHIFT) INC SRC2 NEXT Y END IF END IF END SUB SUB PXL_TEXT( PX, PY, S$, MODE, USE_HI ) L = LEN( S$ ) X = PX W = 8 IF ABS( MODE ) = 2 THEN USE_RECT = TRUE SPRITEMODE = -1 SPRITEINV = FALSE RECTMODE = ( MODE = 2 ) + 1 PX2 = PXL_PXHI - 1 IF PXL_USETXMETA THEN H = PEEK( PXL_TXMETAADDR + 96 ) ELSE H = 8 PY2 = MIN( PY + H - 1, PXL_PYHI - 1 ) ELSE USE_RECT = FALSE SPRITEMODE = MODE SPRITEINV = MODE = 0 END IF SWAP PXL_SPRITEADDR, PXL_TEXTADDR FOR P = 1 TO L IF X >= PXL_PXHI THEN EXIT C = ASC( MID$( S$, P, 1 ) ) + PXL_FONT IF PXL_USETXMETA THEN W = PEEK( PXL_TXMETAADDR + C ) IF USE_RECT THEN CALL PXL_RECT( X,PY, MIN(X+W-1,PX2),PY2, RECTMODE,USE_HI ) CALL PXL_SPRITE( X, PY, C / 2, SPRITEMODE, USE_HI, SPRITEINV ) ADD X, W NEXT P SWAP PXL_SPRITEADDR, PXL_TEXTADDR END SUB SUB PXL_PRINT( PX, PY, S$, MODE, USE_HI ) L = LEN( S$ ) X = PX W = 8 Y = PY IF PXL_USETXMETA THEN H = PEEK( PXL_TXMETAADDR + 96 ) ELSE H = 8 IF ABS( MODE ) = 2 THEN USE_RECT = TRUE SPRITEMODE = -1 SPRITEINV = FALSE RECTMODE = ( MODE = 2 ) + 1 PX2 = PXL_PXHI - 1 IF PXL_USETXMETA THEN H = PEEK( PXL_TXMETAADDR + 96 ) ELSE H = 8 PY2 = PXL_PYHI - 1 ELSE USE_RECT = FALSE SPRITEMODE = MODE SPRITEINV = MODE = 0 END IF SWAP PXL_SPRITEADDR, PXL_TEXTADDR FOR P = 1 TO L C = ASC( MID$( S$, P, 1 ) ) IF C = 10 THEN X = PX ADD Y, H ELSE IF X >= PXL_PXHI OR Y >= PXL_PYHI THEN EXIT ADD C, PXL_FONT IF PXL_USETXMETA THEN W = PEEK( PXL_TXMETAADDR + C ) IF X + W >= PXL_PXHI THEN X = PX ADD Y, H END IF IF USE_RECT THEN CALL PXL_RECT( X,Y, MIN( X+W-1,PX2),MIN( Y+H-1,PY2), RECTMODE,USE_HI) CALL PXL_SPRITE( X, Y, C / 2, SPRITEMODE, USE_HI, SPRITEINV ) ADD X, W END IF NEXT P SWAP PXL_SPRITEADDR, PXL_TEXTADDR END SUB SUB ARIAL8PT_PRINT( PX, PY, S$, MODE, USE_HI ) L = LEN( S$ ) X = PX Y = PY H = PEEK( PXL_TXMETAADDR + 96 ) IF ABS( MODE ) = 2 THEN USE_RECT = TRUE SPRITEMODE = -1 SPRITEINV = FALSE RECTMODE = ( MODE = 2 ) + 1 PX2 = PXL_PXHI - 1 PY2 = PXL_PYHI - 1 ELSE USE_RECT = FALSE SPRITEMODE = MODE SPRITEINV = MODE = 0 END IF D1$ = "$(),;@[]_" + CHR$(103) + CHR$(106) + CHR$(112) + CHR$(113) + CHR$(121) + "{|}" D2$ = "%@W" + CHR$(119) SWAP PXL_SPRITEADDR, PXL_TEXTADDR FOR P = 1 TO L A$ = MID$( S$, P, 1 ) C = ASC( A$ ) IF C = 10 THEN X = PX ADD Y, H ELSE IF X >= PXL_PXHI OR Y >= PXL_PYHI THEN EXIT ADD C, PXL_FONT W = PEEK( PXL_TXMETAADDR + C ) IF X + W >= PXL_PXHI THEN X = PX ADD Y, H END IF IF USE_RECT THEN CALL PXL_RECT( X,Y, MIN(X+W-1,PX2),MIN(Y+H-1,PY2), RECTMODE,USE_HI) CALL PXL_SPRITE ( X , Y , C/2 , SPRITEMODE,USE_HI,SPRITEINV ) A = INSTR( D1$, A$ ) / 2 IF A THEN CALL PXL_SPRITE( X , Y+8, A+47.5, SPRITEMODE,USE_HI,SPRITEINV ) A = INSTR( D2$, A$ ) / 2 IF A THEN CALL PXL_SPRITE( X+8, Y , A+56.0, SPRITEMODE,USE_HI,SPRITEINV ) IF A$ = "@" THEN CALL PXL_SPRITE( X+8, Y+8, 58.5, SPRITEMODE,USE_HI,SPRITEINV ) ADD X, W END IF NEXT P SWAP PXL_SPRITEADDR, PXL_TEXTADDR END SUB SUB PXL_SAVE( PX, PY, W, H, DSTADDR, USE_HI, RETURN_SAVESIZE ) POKE DSTADDR, W POKE DSTADDR + 1, H X2 = PX + W - 1 Y2 = PY + H - 1 SRCBASE = 8 AND USE_HI DST = DSTADDR + 2 FOR Y = PY TO Y2 SRCBASE2 = SRCBASE + PXL_YADDR( Y ) FOR X = PX TO X2 STEP 8 POKE DST, PEEK( SRCBASE2 + PXL_XADDR( X ) ) INC DST NEXT X NEXT Y RETURN_SAVESIZE = DST - DSTADDR END SUB SUB PXL_LOAD( PX, PY, SRCADDR, USE_HI ) X2 = PX + PEEK( SRCADDR ) - 1 Y2 = PY + PEEK( SRCADDR + 1 ) - 1 SRCBASE = 8 AND USE_HI SRC = SRCADDR + 2 FOR Y = PY TO Y2 IF Y >= PXL_PYHI THEN EXIT SUB SRCBASE2 = SRCBASE + PXL_YADDR( Y ) FOR X = PX TO X2 STEP 8 IF X < PXL_PXHI THEN POKE SRCBASE2 + PXL_XADDR( X ), PEEK( SRC ) INC SRC NEXT X NEXT Y END SUB SUB PXL2_SETP( PX, PY, PC ) DST = PXL_XADDR( PX ) + PXL_YADDR( PY ) IF PC AND 1 THEN POKE DST,PEEK(DST) OR PXL_MASKS(PX) ELSE POKE DST,PEEK(DST) AND PXL_MASKX(PX) ADD DST, 8 IF PC AND 2 THEN POKE DST,PEEK(DST) OR PXL_MASKS(PX) ELSE POKE DST,PEEK(DST) AND PXL_MASKX(PX) END SUB SUB PXL2_SETP_CLIP( PX, PY, PC ) IF PX < 0 OR PX >= PXL_PXHI OR PY < 0 OR PY >= PXL_PYHI THEN EXIT SUB DST = PXL_XADDR( PX ) + PXL_YADDR( PY ) IF PC AND 1 THEN POKE DST,PEEK(DST) OR PXL_MASKS(PX) ELSE POKE DST,PEEK(DST) AND PXL_MASKX(PX) ADD DST, 8 IF PC AND 2 THEN POKE DST,PEEK(DST) OR PXL_MASKS(PX) ELSE POKE DST,PEEK(DST) AND PXL_MASKX(PX) END SUB SUB PXL2_SETF( FX, FY, PC ) DST = PXL_XADDR( FX + 0.5 ) + PXL_YADDR( FY + 0.5 ) IF PC AND 1 THEN POKE DST,PEEK(DST) OR PXL_MASKS(FX+0.5) ELSE POKE DST,PEEK(DST) AND PXL_MASKX(FX+0.5) ADD DST, 8 IF PC AND 2 THEN POKE DST,PEEK(DST) OR PXL_MASKS(FX+0.5) ELSE POKE DST,PEEK(DST) AND PXL_MASKX(FX+0.5) END SUB SUB PXL2_SETF_CLIP( FX, FY, PC ) IF FX < -0.5 OR FX >= PXL_FXHI OR FY <= -0.5 OR FY >= PXL_FYHI THEN EXIT SUB DST = PXL_XADDR( FX + 0.5 ) + PXL_YADDR( FY + 0.5 ) IF PC AND 1 THEN POKE DST,PEEK(DST) OR PXL_MASKS(FX+0.5) ELSE POKE DST,PEEK(DST) AND PXL_MASKX(FX+0.5) ADD DST, 8 IF PC AND 2 THEN POKE DST,PEEK(DST) OR PXL_MASKS(FX+0.5) ELSE POKE DST,PEEK(DST) AND PXL_MASKX(FX+0.5) END SUB SUB PXL2_TESTP( PX, PY, RETURN_PC ) DST = PXL_XADDR( PX ) + PXL_YADDR( PY ) IF PEEK( DST ) AND PXL_MASKS( PX ) THEN RETURN_PC = 1 ELSE RETURN_PC = 0 IF PEEK( DST + 8 ) AND PXL_MASKS( PX ) THEN ADD RETURN_PC, 2 END SUB SUB PXL2_TESTP_CLIP( PX, PY, RETURN_PC ) IF PX < 0 OR PX >= PXL_PXHI OR PY < 0 OR PY >= PXL_PYHI THEN EXIT SUB DST = PXL_XADDR( PX ) + PXL_YADDR( PY ) IF PEEK( DST ) AND PXL_MASKS( PX ) THEN RETURN_PC = 1 ELSE RETURN_PC = 0 IF PEEK( DST + 8 ) AND PXL_MASKS( PX ) THEN ADD RETURN_PC, 2 END SUB SUB PXL2_TESTF( FX, FY, RETURN_PC ) DST = PXL_XADDR( FX + 0.5 ) + PXL_YADDR( FY + 0.5 ) IF PEEK( DST ) AND PXL_MASKS( FX + 0.5 ) THEN RETURN_PC = 1 ELSE RETURN_PC = 0 IF PEEK( DST + 8 ) AND PXL_MASKS( FX + 0.5 ) THEN ADD RETURN_PC, 2 END SUB SUB PXL2_TESTF_CLIP( FX, FY, RETURN_PC ) IF FX < -0.5 OR FX >= PXL_FXHI OR FY <= -0.5 OR FY >= PXL_FYHI THEN EXIT SUB ADDR = PXL_XADDR( FX + 0.5 ) + PXL_YADDR( FY + 0.5 ) IF PEEK( ADDR ) AND PXL_MASKS( FX + 0.5 ) THEN RETURN_PC = 1 ELSE RETURN_PC = 0 IF PEEK( ADDR + 8 ) AND PXL_MASKS( FX + 0.5 ) THEN ADD RETURN_PC, 2 END SUB SUB PXL2_VERT( FX, FY1, FY2, PC ) CALL PXL_VERT( FX, FY1, FY2, PC AND 1, FALSE ) CALL PXL_VERT( FX, FY1, FY2, ( PC AND 2 ) \ 2, TRUE ) END SUB SUB PXL2_VERT_CLIP( FX, FY1, FY2, PC ) IF -0.5 <= FX AND FX < PXL_FXHI AND -0.5 <= FY2 AND FY1 < PXL_FYHI THEN CALL PXL2_VERT( FX, MAX( 0, FY1 ), MIN( PXL_PYHI - 1, FY2 ), PC ) END SUB SUB PXL2_HORZ( FX1, FX2, FY, PC ) CALL PXL_HORZ( FX1, FX2, FY, PC AND 1, FALSE ) CALL PXL_HORZ( FX1, FX2, FY, ( PC AND 2 ) \ 2, TRUE ) END SUB SUB PXL2_HORZ_CLIP( FX1, FX2, FY, PC ) IF -0.5 <= FX2 AND FX1 < 159.5 AND -0.5 <= FY AND FY < 127.5 THEN CALL PXL2_HORZ( MAX( 0, FX1 ), MIN( 159, FX2 ), FY, PC ) END SUB SUB PXL2_CIRC( FX, FY, FR, PC ) CALL PXL_CIRC( FX, FY, FR, PC AND 1, FALSE ) CALL PXL_CIRC( FX, FY, FR, ( PC AND 2 ) \ 2, TRUE ) END SUB SUB PXL2_CIRC_CLIP( FX, FY, FR, PC ) CALL PXL_CIRC_CLIP( FX, FY, FR, PC AND 1, FALSE ) CALL PXL_CIRC_CLIP( FX, FY, FR, ( PC AND 2 ) \ 2, TRUE ) END SUB SUB PXL2_CIRCFILL( FX, FY, FR, PC ) CALL PXL_CIRCFILL( FX, FY, FR, PC AND 1, FALSE ) CALL PXL_CIRCFILL( FX, FY, FR, ( PC AND 2 ) \ 2, TRUE ) END SUB SUB PXL2_CIRCFILL_CLIP( FX, FY, FR, PC ) CALL PXL_CIRCFILL_CLIP( FX, FY, FR, PC AND 1, FALSE ) CALL PXL_CIRCFILL_CLIP( FX, FY, FR, ( PC AND 2 ) \ 2, TRUE ) END SUB SUB PXL2_LINE( FX1, FY1, FX2, FY2, PC ) CALL PXL_LINE( FX1, FY1, FX2, FY2, PC AND 1, FALSE ) CALL PXL_LINE( FX1, FY1, FX2, FY2, ( PC AND 2 ) \ 2, TRUE ) END SUB SUB PXL2_LINE_CLIP( FX1, FY1, FX2, FY2, PC ) CALL PXL_LINE_CLIP( FX1, FY1, FX2, FY2, PC AND 1, FALSE ) CALL PXL_LINE_CLIP( FX1, FY1, FX2, FY2, ( PC AND 2 ) \ 2, TRUE ) END SUB SUB PXL2_RECT( FX1, FY1, FX2, FY2, PC ) CALL PXL_RECT( FX1, FY1, FX2, FY2, PC AND 1, FALSE ) CALL PXL_RECT( FX1, FY1, FX2, FY2, ( PC AND 2 ) \ 2, TRUE ) END SUB SUB PXL2_RECT_CLIP( FX1, FY1, FX2, FY2, PC ) CALL PXL_RECT_CLIP( FX1, FY1, FX2, FY2, PC AND 1, FALSE ) CALL PXL_RECT_CLIP( FX1, FY1, FX2, FY2, ( PC AND 2 ) \ 2, TRUE ) END SUB SUB PXL2_TRIFAST( FX1, FY1, FX2, FY2, FX3, FY3, MODE, USE_HI ) CALL PXL_TRIFAST( FX1, FY1, FX2, FY2, FX3, FY3, PC AND 1, FALSE ) CALL PXL_TRIFAST( FX1, FY1, FX2, FY2, FX3, FY3, ( PC AND 2 ) / 2, TRUE ) END SUB SUB PXL2_TRIFAST_CLIP( FX1, FY1, FX2, FY2, FX3, FY3, MODE, USE_HI ) CALL PXL_TRIFAST_CLIP( FX1, FY1, FX2, FY2, FX3, FY3, PC AND 1, FALSE ) CALL PXL_TRIFAST_CLIP( FX1, FY1, FX2, FY2, FX3, FY3, ( PC AND 2 ) / 2, TRUE ) END SUB SUB PXL2_TESSFAST( FX1, FY1, FX2, FY2, FX3, FY3, MODE, USE_HI ) CALL PXL_TESSFAST( FX1, FY1, FX2, FY2, FX3, FY3, PC AND 1, FALSE ) CALL PXL_TESSFAST( FX1, FY1, FX2, FY2, FX3, FY3, ( PC AND 2 ) \ 2, TRUE ) END SUB SUB PXL2_TESSFAST_CLIP( FX1, FY1, FX2, FY2, FX3, FY3, MODE, USE_HI ) CALL PXL_TESSFAST_CLIP( FX1, FY1, FX2, FY2, FX3, FY3, PC AND 1, FALSE ) CALL PXL_TESSFAST_CLIP( FX1, FY1, FX2, FY2, FX3, FY3, ( PC AND 2 ) \ 2, TRUE ) END SUB SUB PXL2_CELL( PX, PY, C, MODE ) Y2 = MIN( ( PY AND $7E ) + 7, PXL_PYHI - 1 ) SRC = PXL_SPRITEADDR + 16 * C IF MODE = 3 THEN FOR Y = PY AND $7E TO Y2 STEP 2 DST = PXL_XADDR( PX ) + PXL_YADDR( Y ) MASK = NOT( PEEKW( SRC ) OR PEEKW( SRC + 8 ) ) POKEW DST, PEEKW( DST ) AND MASK OR PEEKW( SRC ) POKEW DST + 8, PEEKW( DST + 8 ) AND MASK OR PEEKW( SRC + 8 ) ADD SRC, 2 NEXT Y ELSE FOR Y = PY AND $7E TO Y2 STEP 2 DST = PXL_XADDR( PX ) + PXL_YADDR( Y ) POKEW DST, PEEKW( SRC ) POKEW DST + 8, PEEKW( SRC + 8 ) ADD SRC, 2 NEXT Y END IF END SUB SUB PXL2_SPRITE( PX, PY, C, MODE ) Y2 = MIN( PY + 7, PXL_PYHI - 1 ) DSTBASE = PXL_XADDR( PX ) SRC1 = PXL_SPRITEADDR + 16 * C SRC2 = SRC1 COL = PX MOD 8 BITSHIFT = 2 ^ COL IF MODE = 3 THEN FOR Y = PY TO Y2 DST = DSTBASE + PXL_YADDR( Y ) MASK = ( PEEK(SRC1) OR PEEK(SRC1+8) XOR $FFFF ) \ BITSHIFT POKE DST, PEEK(DST) AND MASK OR PEEK(SRC1) \ BITSHIFT POKE DST+8, PEEK(DST+8) AND MASK OR PEEK(SRC1+8) \ BITSHIFT INC SRC1 NEXT Y IF COL AND PX + 8 < PXL_PXHI THEN DSTBASE = PXL_XADDR( PX + 8 ) BITSHIFT = 2 ^ ( 8 - COL ) FOR Y = PY TO Y2 DST = DSTBASE + PXL_YADDR( Y ) MASK = NOT ( PEEK(SRC2) OR PEEK(SRC2+8) ) * BITSHIFT OR PXL_MASKR(PX) POKE DST, PEEK(DST) AND MASK OR PEEK(SRC2) * BITSHIFT POKE DST+8, PEEK(DST+8) AND MASK OR PEEK(SRC2+8) * BITSHIFT INC SRC2 NEXT Y END IF ELSE FOR Y = PY TO Y2 DST = DSTBASE + PXL_YADDR( Y ) POKE DST, PEEK(DST ) AND PXL_MASKW(PX) OR PEEK(SRC1 ) \ BITSHIFT POKE DST+8, PEEK(DST+8) AND PXL_MASKW(PX) OR PEEK(SRC1+8) \ BITSHIFT INC SRC1 NEXT Y IF COL AND PX + 8 < PXL_PXHI THEN DSTBASE = PXL_XADDR( PX + 8 ) BITSHIFT = 2 ^ ( 8 - COL ) FOR Y = PY TO Y2 DST = DSTBASE + PXL_YADDR( Y ) POKE DST, PEEK(DST ) AND PXL_MASKR(PX) OR PEEK(SRC2 ) * BITSHIFT POKE DST+8, PEEK(DST+8) AND PXL_MASKR(PX) OR PEEK(SRC2+8) * BITSHIFT INC SRC2 NEXT Y END IF END IF END SUB SUB PXL2_TEXT( PX, PY, S$, MODE ) L = LEN( S$ ) X = PX W = 8 IF MODE = 2 THEN USE_RECT = TRUE PX2 = PXL_PXHI - 1 IF PXL_USETXMETA THEN H = PEEK( PXL_TXMETAADDR + 96 ) ELSE H = 8 PY2 = MIN( PY + H - 1, PXL_PYHI - 1 ) ELSE USE_RECT = FALSE END IF SWAP PXL_SPRITEADDR, PXL_TEXTADDR FOR P = 1 TO L IF X >= PXL_PXHI THEN EXIT C = ASC( MID$( S$, P, 1 ) ) + PXL_FONT IF PXL_USETXMETA THEN W = PEEK( PXL_TXMETAADDR + C ) IF USE_RECT THEN CALL PXL_RECT( X, PY, MIN( X + W - 1, PX2 ), PY2, 0 ) CALL PXL2_SPRITE( X, PY, C, 3 ) ADD X, W NEXT P SWAP PXL_SPRITEADDR, PXL_TEXTADDR END SUB SUB PXL2_PRINT( PX, PY, S$, MODE ) L = LEN( S$ ) X = PX W = 8 Y = PY IF PXL_USETXMETA THEN H = PEEK( PXL_TXMETAADDR + 96 ) ELSE H = 8 IF MODE = 2 THEN USE_RECT = TRUE PX2 = PXL_PXHI - 1 PY2 = PXL_PYHI - 1 ELSE USE_RECT = FALSE END IF SWAP PXL_SPRITEADDR, PXL_TEXTADDR FOR P = 1 TO L C = ASC( MID$( S$, P, 1 ) ) IF C = 10 THEN X = PX ADD Y, H ELSE IF X >= PXL_PXHI OR Y >= PXL_PYHI THEN EXIT ADD C, PXL_FONT IF PXL_USETXMETA THEN W = PEEK( PXL_TXMETAADDR + C ) IF X + W >= PXL_PXHI THEN X = PX ADD Y, H END IF IF USE_RECT THEN CALL PXL2_RECT(X,Y, MIN(X+W-1,PX2),MIN(Y+H-1,PY2), 0 ) CALL PXL2_SPRITE( X, Y, C, 3 ) ADD X, W END IF NEXT P SWAP PXL_SPRITEADDR, PXL_TEXTADDR END SUB SUB PXL2_SAVE( PX, PY, W, H, DSTADDR, RETURN_SAVESIZE ) POKE DSTADDR, W POKE DSTADDR + 1, H X2 = PX + W - 1 Y2 = PY + H - 1 DST = DSTADDR + 2 FOR Y = PY TO Y2 SRCBASE = PXL_YADDR( Y ) FOR X = PX TO X2 STEP 8 POKE DST, PEEK( SRCBASE + PXL_XADDR( X ) ) INC DST POKE DST, PEEK( SRCBASE + PXL_XADDR( X ) + 8 ) INC DST NEXT X NEXT Y RETURN_SAVESIZE = DST - DSTADDR END SUB SUB PXL2_LOAD( PX, PY, SRCADDR ) X2 = PX + PEEK( SRCADDR ) - 1 Y2 = PY + PEEK( SRCADDR + 1 ) - 1 SRC = SRCADDR + 2 FOR Y = PY TO Y2 IF Y >= PXL_PYHI THEN EXIT SUB SRCBASE = PXL_YADDR( Y ) FOR X = PX TO X2 STEP 8 IF X < PXL_PXHI THEN POKE SRCBASE + PXL_XADDR( X ), PEEK( SRC ) INC SRC POKE SRCBASE + PXL_XADDR( X ) + 8, PEEK( SRC ) INC SRC ELSE ADD SRC, 2 END IF NEXT X NEXT Y END SUB SUB PXL3_SETP( PX, PY, PC ) DST = PXL_XADDR( PX ) + PXL_YADDR( PY ) IF DST AND 1 THEN M = $AA ELSE M = $55 IF PC MOD 2 THEN POKE DST, PEEK(DST) AND PXL_MASKX(PX) OR PXL_MASKS(PX) AND M ELSE IF PC MOD 4 = 0 THEN POKE DST, PEEK(DST) AND PXL_MASKX(PX) ELSE POKE DST, PEEK(DST) OR PXL_MASKS(PX) END IF ADD DST, 8 IF PC <= 2 THEN POKE DST, PEEK(DST) AND PXL_MASKX(PX) ELSE IF PC = 3 THEN POKE DST, PEEK(DST) AND PXL_MASKX(PX) OR PXL_MASKS(PX) AND NOT M ELSE IF PC <= 6 THEN POKE DST, PEEK(DST) OR PXL_MASKS(PX) ELSE POKE DST, PEEK(DST) AND PXL_MASKX(PX) OR PXL_MASKS(PX) AND M END IF END SUB SUB PXL3_SETP_CLIP( PX, PY, PC ) IF PX>=0 AND PX=0 AND PY=PXL_FXHI OR FY<=-0.5 OR FY>=PXL_FYHI THEN CALL PXL3_SETP(FX+0.5,FY+0.5,PC) END SUB #3:PXL BG 00001410010101020201020203010302 04010402050105020601060207010702 08010802090109020A010A020B010B02 0C010C020D010D020E010E020F010F02 10011002110111021201120213011302 14011402150115021601160217011702 18011802190119021A011A021B011B02 1C011C021D011D021E011E021F011F02 20012002210121022201220223012302 24012402250125022601260227012702 28012802290129022A012A022B012B02 2C012C022D012D022E012E022F012F02 30013002310131023201320233013302 34013402350135023601360237013702 38013802390139023A013A023B013B02 3C013C023D013D023E013E023F013F02 40014002410141024201420243014302 44014402450145024601460247014702 48014802490149024A014A024B014B02 4C014C024D014D024E014E024F014F02 50015002510151025201520253015302 54015402550155025601560257015702 58015802590159025A015A025B015B02 5C015C025D015D025E015E025F015F02 60016002610161026201620263016302 64016402650165026601660267016702 68016802690169026A016A026B016B02 6C016C026D016D026E016E026F016F02 70017002710171027201720273017302 74017402750175027601760277017702 78017802790179027A017A027B017B02 7C017C027D017D027E017E027F017F02 80018002810181028201820283018302 84018402850185028601860287018702 88018802890189028A018A028B018B02 8C018C028D018D028E018E028F018F02 90019002910191029201920293019302 94019402950195029601960297019702 98019802990199029A019A029B019B02 9C019C029D019D029E019E029F019F02 A001A002 #4:PXL METADATA 4E42A08001021000008A002000800080 00800000100000801800A08020004081 2800E08130008082380020834000C083 48006084500000855800A08560004086 6800E08670008087780020888000C088 8800608990009800A000A800