GLOBAL SYS_CHAR_ADDR, SYS_BG0_ADDR, SYS_BG1_ADDR, SYS_WORK_ADDR, SYS_PERS_ADDR GLOBAL TRUE, FALSE CALL LOWRES_NX DIM GLOBAL PXL_MASKS(7), PXL_MASKX(7), PXL_MASKR(7), PXL_MASKL(7), PXL_MASKW(8) GLOBAL PXL_CHAR, PXL_WIDTH, PXL_HEIGHT, PXL_ADDR, PXL_ADDR_DY, PXL_SIZE CALL MAIN END SUB MAIN BG 1 CALL PXL_FULLSCR_DIR BG 0 CALL SET_TEST CALL STRAIGHT_LINE_TEST CALL RECT_FILL_TEST CALL CIRC_FILL_TEST CALL CIRC_TEST 'NOW THE REAL TEST... PRINT "BENCHMARK" PRINT "(FOR 3D)" T = TIMER CALL LINE_TEST FRAMES = TIMER - T LINES = 2 * ( PXL_WIDTH + PXL_HEIGHT ) * 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 PXL_SET( PX, PY, MODE ) ADDR = PXL_ADDR + PXL_ADDR_DY * ( PX \ 8 ) + PY IF MODE = 1 THEN POKE ADDR, PEEK(ADDR) OR PXL_MASKS( PX AND 7 ) ELSE IF MODE THEN POKE ADDR, PEEK(ADDR) XOR PXL_MASKS( PX AND 7 ) ELSE POKE ADDR, PEEK(ADDR) AND PXL_MASKX( PX AND 7 ) END IF END SUB SUB PXL_SET_CLIP( PX, PY, MODE ) IF PX >= 0 AND PX < PXL_WIDTH AND PY >= 0 AND PY < PXL_HEIGHT THEN CALL PXL_SET( PX, PY, MODE ) END SUB SUB PXL_TEST( PX, PY, RETURN_FLAG ) ADDR = PXL_ADDR + PXL_ADDR_DY * ( PX \ 8 ) + PY RETURN_FLAG = PEEK( ADDR ) AND PXL_MASKS( PX AND 7 ) END SUB SUB PXL_VERT( PX, PY, HEIGHT, MODE ) ADDR = PXL_ADDR + PXL_ADDR_DY * ( PX \ 8 ) + PY ADDR2 = ADDR + HEIGHT - 1 IF MODE = 1 THEN MASK = PXL_MASKS( PX AND 7 ) FOR ADDR = ADDR TO ADDR2 POKE ADDR, PEEK( ADDR ) OR MASK NEXT ADDR ELSE IF MODE THEN MASK = PXL_MASKS( PX AND 7 ) FOR ADDR = ADDR TO ADDR2 POKE ADDR, PEEK( ADDR ) XOR MASK NEXT ADDR ELSE MASK = PXL_MASKX( PX AND 7 ) FOR ADDR = ADDR TO ADDR2 POKE ADDR, PEEK( ADDR ) AND MASK NEXT ADDR END IF END SUB SUB PXL_VERT_CLIP( PX, PY, HEIGHT, MODE ) IF PX >= 0 AND PX < PXL_WIDTH THEN H = HEIGHT IF PY < 0 THEN ADD H, PY Y = 0 ELSE Y = PY END IF IF Y + H > PXL_HEIGHT THEN H = PXL_HEIGHT - Y CALL PXL_VERT( PX, Y, H, MODE ) END IF END SUB SUB PXL_HORZ( PX, PY, WIDTH, MODE ) PX2 = PX + WIDTH - 1 ADDR = PXL_ADDR + PXL_ADDR_DY * ( PX \ 8 ) + PY ADDR2 = PXL_ADDR + PXL_ADDR_DY * ( PX2 \ 8 ) + PY BITMASK = PXL_MASKR( PX AND 7 ) BITMASK2 = PXL_MASKL( PX2 AND 7 ) IF ADDR = ADDR2 THEN BITMASK = BITMASK AND BITMASK2 USE_BITMASK2 = FALSE ELSE USE_BITMASK2 = TRUE END IF ADD ADDR2, -PXL_ADDR_DY IF MODE = 1 THEN POKE ADDR, PEEK( ADDR ) OR BITMASK FOR ADDR = ADDR + PXL_ADDR_DY TO ADDR2 STEP PXL_ADDR_DY POKE ADDR, $FF NEXT ADDR IF USE_BITMASK2 THEN POKE ADDR, PEEK( ADDR ) OR BITMASK2 ELSE IF MODE THEN POKE ADDR, PEEK( ADDR ) XOR BITMASK FOR ADDR = ADDR + PXL_ADDR_DY TO ADDR2 STEP PXL_ADDR_DY POKE ADDR, NOT PEEK( ADDR ) NEXT ADDR IF USE_BITMASK2 THEN POKE ADDR, PEEK( ADDR ) XOR BITMASK2 ELSE POKE ADDR, PEEK( ADDR ) AND NOT BITMASK FOR ADDR = ADDR + PXL_ADDR_DY TO ADDR2 STEP PXL_ADDR_DY POKE ADDR, $00 NEXT ADDR IF USE_BITMASK2 THEN POKE ADDR, PEEK( ADDR ) AND NOT BITMASK2 END IF END SUB SUB PXL_HORZ_CLIP( PX, PY, WIDTH, MODE ) IF PY >= 0 AND PY < PXL_HEIGHT THEN W = WIDTH IF PX < 0 THEN ADD W, PX X = 0 ELSE X = PX END IF IF X + W > PXL_WIDTH THEN W = PXL_WIDTH - X CALL PXL_HORZ( X, PY, W, MODE ) END IF END SUB SUB PXL_RECT_FILL( PX, PY, WIDTH, HEIGHT, MODE ) PX2 = PX + WIDTH - 1 ADDR1 = PXL_ADDR + PXL_ADDR_DY * ( PX \ 8 ) + PY ADDR2 = PXL_ADDR + PXL_ADDR_DY * ( PX2 \ 8 ) + PY BITMASK = PXL_MASKR( PX AND 7 ) BITMASK2 = PXL_MASKL( PX2 AND 7 ) IF ADDR1 = ADDR2 THEN BITMASK = BITMASK AND BITMASK2 USE_BITMASK2 = FALSE ELSE USE_BITMASK2 = TRUE END IF ADDR1_END = ADDR1 + HEIGHT - 1 ADD ADDR2, -PXL_ADDR_DY IF MODE = 1 THEN FOR ADDR1 = ADDR1 TO ADDR1_END POKE ADDR1, PEEK( ADDR1 ) OR BITMASK FOR ADDR = ADDR1 + PXL_ADDR_DY TO ADDR2 STEP PXL_ADDR_DY POKE ADDR, $FF NEXT ADDR IF USE_BITMASK2 THEN POKE ADDR, PEEK( ADDR ) OR BITMASK2 INC ADDR2 NEXT ADDR1 ELSE IF MODE THEN FOR ADDR1 = ADDR1 TO ADDR1_END POKE ADDR1, PEEK( ADDR1 ) XOR BITMASK FOR ADDR = ADDR1 + PXL_ADDR_DY TO ADDR2 STEP PXL_ADDR_DY POKE ADDR, NOT PEEK( ADDR ) NEXT ADDR IF USE_BITMASK2 THEN POKE ADDR, PEEK( ADDR ) XOR BITMASK2 INC ADDR2 NEXT ADDR1 ELSE BITMASK = NOT BITMASK BITMASK2 = NOT BITMASK2 FOR ADDR1 = ADDR1 TO ADDR1_END POKE ADDR1, PEEK( ADDR1 ) AND BITMASK FOR ADDR = ADDR1 + PXL_ADDR_DY TO ADDR2 STEP PXL_ADDR_DY POKE ADDR, $00 NEXT ADDR IF USE_BITMASK2 THEN POKE ADDR, PEEK( ADDR ) AND BITMASK2 INC ADDR2 NEXT ADDR1 END IF END SUB SUB PXL_RECT_FILL_CLIP( PX, PY, WIDTH, HEIGHT, MODE ) H = HEIGHT IF PY < 0 THEN ADD H, PY Y = 0 ELSE Y = PY END IF IF Y + H > PXL_HEIGHT THEN H = PXL_HEIGHT - Y W = WIDTH IF PX < 0 THEN ADD W, PX X = 0 ELSE X = PX END IF IF X + W > PXL_WIDTH THEN W = PXL_WIDTH - X CALL PXL_RECT_FILL( X, Y, W, H, MODE ) END SUB SUB PXL_CIRC_FILL( PXC, PYC, RADIUS, MODE ) PX1 = PXC - RADIUS PX2 = PXC + RADIUS PY1 = MAX( PYC - RADIUS, 0 ) PY2 = MIN( PYC + RADIUS, PXL_HEIGHT - 1 ) DISTANCE = ( RADIUS + 0.25 ) ^ 2 DY = PY1 - PYC DX_SAVE = PX1 - PXC FOR Y = PY1 TO PY2 DX = DX_SAVE FOR X = PX1 TO PX2 IF DX ^ 2 + DY ^ 2 <= DISTANCE THEN WIDTH = 2 * ( PXC - X ) + 1 CALL PXL_HORZ( X, Y, WIDTH, MODE ) X = PX2 END IF INC DX NEXT X INC DY NEXT Y END SUB SUB PXL_CIRC_FILL_CLIP( PXC, PYC, RADIUS, MODE ) PX1 = PXC - RADIUS PX2 = PXC + RADIUS PY1 = MAX( PYC - RADIUS, 0 ) PY2 = MIN( PYC + RADIUS, PXL_HEIGHT - 1 ) DISTANCE = ( RADIUS + 0.25 ) ^ 2 DY = PY1 - PYC DX_SAVE = PX1 - PXC FOR Y = PY1 TO PY2 DX = DX_SAVE FOR X = PX1 TO PX2 IF DX ^ 2 + DY ^ 2 <= DISTANCE THEN WIDTH = 2 * ( PXC - X ) + 1 IF X < 0 THEN ADD WIDTH, X X = 0 END IF IF X + WIDTH > PXL_WIDTH THEN WIDTH = PXL_WIDTH - X CALL PXL_HORZ( X, Y, WIDTH, MODE ) X = PX2 END IF INC DX NEXT X INC DY NEXT Y END SUB 'NOT OPTIMIZED! SUB PXL_CIRC( XC, YC, R, MODE ) F = 1 - R DDFX = 0 DDFY = -2 * R X = 0 Y = R CALL PXL_SET( XC + R, YC, MODE ) CALL PXL_SET( XC, YC - R, MODE ) CALL PXL_SET( XC - R, YC, MODE ) CALL PXL_SET( XC, YC + R, MODE ) WHILE X + 1 < Y IF F >= 0 THEN DEC Y ADD DDFY, 2 ADD F, DDFY END IF INC X ADD DDFX, 2 ADD F, DDFX + 1 CALL PXL_SET( XC + Y, YC - X, MODE ) CALL PXL_SET( XC - X, YC - Y, MODE ) CALL PXL_SET( XC - Y, YC + X, MODE ) CALL PXL_SET( XC + X, YC + Y, MODE ) IF X <> Y THEN CALL PXL_SET( XC + X, YC - Y, MODE ) CALL PXL_SET( XC - Y, YC - X, MODE ) CALL PXL_SET( XC - X, YC + Y, MODE ) CALL PXL_SET( XC + Y, YC + X, MODE ) END IF WEND END SUB 'NOT OPTIMIZED! SUB PXL_CIRC_CLIP( XC, YC, R, MODE ) F = 1 - R DDFX = 0 DDFY = -2 * R X = 0 Y = R CALL PXL_SET_CLIP( XC + R, YC, MODE ) CALL PXL_SET_CLIP( XC, YC - R, MODE ) CALL PXL_SET_CLIP( XC - R, YC, MODE ) CALL PXL_SET_CLIP( XC, YC + R, MODE ) WHILE X + 1 < Y IF F >= 0 THEN DEC Y ADD DDFY, 2 ADD F, DDFY END IF INC X ADD DDFX, 2 ADD F, DDFX + 1 CALL PXL_SET_CLIP( XC + Y, YC - X, MODE ) CALL PXL_SET_CLIP( XC - X, YC - Y, MODE ) CALL PXL_SET_CLIP( XC - Y, YC + X, MODE ) CALL PXL_SET_CLIP( XC + X, YC + Y, MODE ) IF X <> Y THEN CALL PXL_SET_CLIP( XC + X, YC - Y, MODE ) CALL PXL_SET_CLIP( XC - Y, YC - X, MODE ) CALL PXL_SET_CLIP( XC - X, YC + Y, MODE ) CALL PXL_SET_CLIP( XC + Y, YC + X, MODE ) END IF WEND END SUB SUB PXL_LINE( PX1, PY1, PX2, PY2, MODE ) DX = PX2 - PX1 DY = PY2 - PY1 SX = SGN( DX ) SY = SGN( DY ) ERROR = 0 IF ABS( DY ) >= ABS( DX ) THEN IF SX = 1 THEN ADDR = PXL_ADDR + PXL_ADDR_DY * ( PX1 \ 8 ) + PY1 BITMASK = PXL_MASKS( PX1 AND 7 ) SLOPE = ABS( DX / DY ) FOR Y = PY1 TO PY2 STEP SY IF MODE = 1 THEN POKE ADDR, PEEK(ADDR) OR BITMASK ELSE IF MODE THEN POKE ADDR, PEEK(ADDR) XOR BITMASK ELSE POKE ADDR, PEEK(ADDR) AND NOT BITMASK END IF ADD ERROR, SLOPE IF ERROR >= 0.5 THEN IF BITMASK <> $01 THEN BITMASK = BITMASK \ 2 ELSE BITMASK = $80 ADD ADDR, PXL_ADDR_DY END IF DEC ERROR END IF ADD ADDR, SY NEXT Y ELSE IF SX THEN ADDR = PXL_ADDR + PXL_ADDR_DY * ( PX1 \ 8 ) + PY1 BITMASK = PXL_MASKS( PX1 AND 7 ) ADDR_DY = -PXL_ADDR_DY SLOPE = ABS( DX / DY ) FOR Y = PY1 TO PY2 STEP SY IF MODE = 1 THEN POKE ADDR, PEEK(ADDR) OR BITMASK ELSE IF MODE THEN POKE ADDR, PEEK(ADDR) XOR BITMASK ELSE POKE ADDR, PEEK(ADDR) AND NOT BITMASK END IF ADD ERROR, SLOPE IF ERROR >= 0.5 THEN IF BITMASK <> $80 THEN ADD BITMASK, BITMASK ELSE BITMASK = $01 ADD ADDR, ADDR_DY END IF DEC ERROR END IF ADD ADDR, SY NEXT Y ELSE CALL PXL_VERT( PX1, MIN( PY1, PY2 ), ABS( PY1 - PY2 ) + 1, MODE ) END IF ELSE IF SX = 1 THEN ADDR = PXL_ADDR + PXL_ADDR_DY * ( PX1 \ 8 ) + PY1 BITMASK = PXL_MASKS( PX1 AND 7 ) SLOPE = ABS( DY / DX ) FOR X = PX1 TO PX2 STEP SX IF MODE = 1 THEN POKE ADDR, PEEK(ADDR) OR BITMASK ELSE IF MODE THEN POKE ADDR, PEEK(ADDR) XOR BITMASK ELSE POKE ADDR, PEEK(ADDR) AND NOT BITMASK END IF ADD ERROR, SLOPE IF ERROR >= 0.5 THEN ADD ADDR, SY DEC ERROR END IF IF BITMASK <> $01 THEN BITMASK = BITMASK \ 2 ELSE BITMASK = $80 ADD ADDR, PXL_ADDR_DY END IF NEXT X ELSE IF SX THEN ADDR = PXL_ADDR + PXL_ADDR_DY * ( PX1 \ 8 ) + PY1 BITMASK = PXL_MASKS( PX1 AND 7 ) ADDR_DY = -PXL_ADDR_DY SLOPE = ABS( DY / DX ) FOR X = PX1 TO PX2 STEP SX IF MODE = 1 THEN POKE ADDR, PEEK(ADDR) OR BITMASK ELSE IF MODE THEN POKE ADDR, PEEK(ADDR) XOR BITMASK ELSE POKE ADDR, PEEK(ADDR) AND NOT BITMASK END IF ADD ERROR, SLOPE IF ERROR >= 0.5 THEN ADD ADDR, SY DEC ERROR END IF IF BITMASK <> $80 THEN ADD BITMASK, BITMASK ELSE BITMASK = $01 ADD ADDR, ADDR_DY END IF NEXT X ELSE CALL PXL_HORZ( MIN( PX1, PX2 ), PY1, ABS( PX1 - PX2 ) + 1, MODE ) END IF END IF END SUB SUB PXL_LINE_CLIP( PX1, PY1, PX2, PY2, MODE ) DX = PX2 - PX1 DY = PY2 - PY1 SX = SGN( DX ) SY = SGN( DY ) PXL_ADDR_MAX = PXL_ADDR + PXL_SIZE ERROR = 0 IF ABS( DY ) >= ABS( DX ) THEN IF SX = 1 THEN ADDR = PXL_ADDR + PXL_ADDR_DY * ( PX1 \ 8 ) + PY1 BITMASK = PXL_MASKS( PX1 AND 7 ) SLOPE = ABS( DX / DY ) FOR Y = PY1 TO PY2 STEP SY IF ADDR >= PXL_ADDR AND ADDR <= PXL_ADDR_MAX THEN IF MODE = 1 THEN POKE ADDR, PEEK(ADDR) OR BITMASK ELSE IF MODE THEN POKE ADDR, PEEK(ADDR) XOR BITMASK ELSE POKE ADDR, PEEK(ADDR) AND NOT BITMASK END IF END IF ADD ERROR, SLOPE IF ERROR >= 0.5 THEN IF BITMASK <> $01 THEN BITMASK = BITMASK \ 2 ELSE BITMASK = $80 ADD ADDR, PXL_ADDR_DY END IF DEC ERROR END IF ADD ADDR, SY NEXT Y ELSE IF SX THEN ADDR = PXL_ADDR + PXL_ADDR_DY * ( PX1 \ 8 ) + PY1 BITMASK = PXL_MASKS( PX1 AND 7 ) ADDR_DY = -PXL_ADDR_DY SLOPE = ABS( DX / DY ) FOR Y = PY1 TO PY2 STEP SY IF ADDR >= PXL_ADDR AND ADDR <= PXL_ADDR_MAX THEN IF MODE = 1 THEN POKE ADDR, PEEK(ADDR) OR BITMASK ELSE IF MODE THEN POKE ADDR, PEEK(ADDR) XOR BITMASK ELSE POKE ADDR, PEEK(ADDR) AND NOT BITMASK END IF END IF ADD ERROR, SLOPE IF ERROR >= 0.5 THEN IF BITMASK <> $80 THEN ADD BITMASK, BITMASK ELSE BITMASK = $01 ADD ADDR, ADDR_DY END IF DEC ERROR END IF ADD ADDR, SY NEXT Y ELSE CALL PXL_VERT_CLIP( PX1, MIN( PY1, PY2 ), ABS( PY1 - PY2 ) + 1, MODE ) END IF ELSE IF SX = 1 THEN ADDR = PXL_ADDR + PXL_ADDR_DY * ( PX1 \ 8 ) + PY1 BITMASK = PXL_MASKS( PX1 AND 7 ) SLOPE = ABS( DY / DX ) FOR X = PX1 TO PX2 STEP SX IF ADDR >= PXL_ADDR AND ADDR <= PXL_ADDR_MAX THEN IF MODE = 1 THEN POKE ADDR, PEEK(ADDR) OR BITMASK ELSE IF MODE THEN POKE ADDR, PEEK(ADDR) XOR BITMASK ELSE POKE ADDR, PEEK(ADDR) AND NOT BITMASK END IF END IF ADD ERROR, SLOPE IF ERROR >= 0.5 THEN ADD ADDR, SY DEC ERROR END IF IF BITMASK <> $01 THEN BITMASK = BITMASK \ 2 ELSE BITMASK = $80 ADD ADDR, PXL_ADDR_DY END IF NEXT X ELSE IF SX THEN ADDR = PXL_ADDR + PXL_ADDR_DY * ( PX1 \ 8 ) + PY1 BITMASK = PXL_MASKS( PX1 AND 7 ) ADDR_DY = -PXL_ADDR_DY SLOPE = ABS( DY / DX ) FOR X = PX1 TO PX2 STEP SX IF ADDR >= PXL_ADDR AND ADDR <= PXL_ADDR_MAX THEN IF MODE = 1 THEN POKE ADDR, PEEK(ADDR) OR BITMASK ELSE IF MODE THEN POKE ADDR, PEEK(ADDR) XOR BITMASK ELSE POKE ADDR, PEEK(ADDR) AND NOT BITMASK END IF END IF ADD ERROR, SLOPE IF ERROR >= 0.5 THEN ADD ADDR, SY DEC ERROR END IF IF BITMASK <> $80 THEN ADD BITMASK, BITMASK ELSE BITMASK = $01 ADD ADDR, ADDR_DY END IF NEXT X ELSE CALL PXL_HORZ_CLIP( MIN( PX1, PX2 ), PY1, ABS( PX1 - PX2 ) + 1, MODE ) END IF END IF END SUB SUB SET_TEST AREA = PXL_WIDTH * PXL_HEIGHT SEQUENCE = 1 FILL PXL_ADDR, PXL_SIZE, $FF FOR MODE = -1 TO 1 IF MODE <> -1 THEN MODE = MODE XOR 1 REPEAT DEC SEQUENCE IF SEQUENCE < AREA THEN CALL PXL_SET( SEQUENCE \ PXL_HEIGHT, SEQUENCE MOD PXL_HEIGHT, MODE ) 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_WIDTH - 1 ) X2 = RND( PXL_WIDTH - 1 ) Y = RND( PXL_HEIGHT - 1 ) IF X1 > X2 THEN SWAP X1, X2 W = X2 - X1 + 1 CALL PXL_HORZ( X1, Y, W, RND( 2 ) - 1 ) X = RND( PXL_WIDTH - 1 ) Y1 = RND( PXL_HEIGHT - 1 ) Y2 = RND( PXL_HEIGHT - 1 ) IF Y1 > Y2 THEN SWAP Y1, Y2 H = Y2 - Y1 + 1 CALL PXL_VERT( X, Y1, H, RND( 2 ) - 1 ) NEXT I FOR Y = 0 TO PXL_HEIGHT - 1 CALL PXL_HORZ( 0, Y, PXL_WIDTH, -1 ) IF Y AND 2 THEN WAIT VBL NEXT Y FOR X = 0 TO PXL_WIDTH - 1 CALL PXL_VERT( X, 0, PXL_HEIGHT, -1 ) IF X AND 2 THEN WAIT VBL NEXT X FOR Y = 0 TO PXL_HEIGHT - 1 CALL PXL_HORZ( 0, Y, PXL_WIDTH, 0 ) IF Y AND 2 THEN WAIT VBL NEXT Y END SUB SUB RECT_FILL_TEST FOR I = 1 TO 50 X1 = RND( PXL_WIDTH - 1 ) X2 = RND( PXL_WIDTH - 1 ) IF X1 > X2 THEN SWAP X1, X2 Y1 = RND( PXL_HEIGHT - 1 ) Y2 = RND( PXL_HEIGHT - 1 ) IF Y1 > Y2 THEN SWAP Y1, Y2 W = X2 - X1 + 1 H = Y2 - Y1 + 1 M = RND( 2 ) - 1 CALL PXL_RECT_FILL( X1, Y1, W, H, M ) NEXT I X = PXL_WIDTH \ 2 Y = PXL_HEIGHT \ 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 CALL PXL_RECT_FILL( X - I \ 2, Y - I \ 2, I, I, MODE ) IF MODE = -1 THEN WAIT VBL CALL PXL_RECT_FILL( X - I \ 2, Y - I \ 2, I, I, MODE ) END IF NEXT I IF MODE = -1 THEN DEC I CALL PXL_RECT_FILL( X - I \ 2, Y - I \ 2, I, I, MODE ) END IF NEXT J FILL PXL_ADDR, PXL_SIZE END SUB SUB CIRC_FILL_TEST FOR I = 1 TO 50 X1 = RND( PXL_WIDTH - 1 ) X2 = RND( PXL_WIDTH - 1 ) IF X1 > X2 THEN SWAP X1, X2 Y1 = RND( PXL_HEIGHT - 1 ) Y2 = RND( PXL_HEIGHT - 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_CIRC_FILL( XC, YC, R, M ) NEXT I XC = PXL_WIDTH \ 2 YC = PXL_HEIGHT \ 2 FOR J = 1 TO 3 R2 = MIN( PXL_WIDTH, PXL_HEIGHT ) \ 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_CIRC_FILL( XC, YC, R, MODE ) IF MODE = -1 THEN WAIT VBL CALL PXL_CIRC_FILL( XC, YC, R, -1 ) END IF NEXT R IF MODE = -1 THEN CALL PXL_CIRC_FILL( XC, YC, R2, -1 ) END IF NEXT J R = MAX( PXL_WIDTH, PXL_HEIGHT ) + 5 CALL PXL_CIRC_FILL_CLIP( PXL_WIDTH - 1, 0, R, 1 ) WAIT 60 CALL PXL_CIRC_FILL_CLIP( PXL_WIDTH - 1, PXL_HEIGHT - 1, R, -1 ) WAIT 60 FILL PXL_ADDR, PXL_SIZE END SUB SUB CIRC_TEST FOR R = 1 TO 205 STEP 3 CALL PXL_CIRC_CLIP( PXL_WIDTH - 1, 0, R, -1 ) CALL PXL_CIRC_CLIP( 0, 0, R, -1 ) CALL PXL_CIRC_CLIP( 0, PXL_HEIGHT - 1, R, -1 ) CALL PXL_CIRC_CLIP( PXL_WIDTH - 1, PXL_HEIGHT - 1, R, -1 ) NEXT R FILL PXL_ADDR, PXL_SIZE 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_WIDTH \ 2 TO PXL_WIDTH - 1 CALL PXL_LINE( PXL_WIDTH \ 2, PXL_HEIGHT \ 2 - 1, X, 0, MODE ) NEXT X FOR Y = 1 TO PXL_HEIGHT \ 2 - 1 CALL PXL_LINE( PXL_WIDTH \ 2, PXL_HEIGHT \ 2 - 1, PXL_WIDTH - 1, Y, MODE ) NEXT Y FOR Y = PXL_HEIGHT \ 2 TO PXL_HEIGHT - 2 CALL PXL_LINE( PXL_WIDTH \ 2, PXL_HEIGHT \ 2, PXL_WIDTH - 1, Y, MODE ) NEXT Y FOR X = PXL_WIDTH - 1 TO PXL_WIDTH \ 2 STEP -1 CALL PXL_LINE( PXL_WIDTH \ 2, PXL_HEIGHT \ 2, X, PXL_HEIGHT - 1, MODE ) NEXT X FOR X = PXL_WIDTH \ 2 - 1 TO 0 STEP -1 CALL PXL_LINE( PXL_WIDTH \ 2 - 1, PXL_HEIGHT \ 2, X, PXL_HEIGHT - 1, MODE ) NEXT X FOR Y = PXL_HEIGHT - 2 TO PXL_HEIGHT / 2 STEP -1 CALL PXL_LINE( PXL_WIDTH \ 2 - 1, PXL_HEIGHT \ 2, 0, Y, MODE ) NEXT Y FOR Y = PXL_HEIGHT \ 2 - 1 TO 1 STEP -1 CALL PXL_LINE( PXL_WIDTH \ 2 - 1, PXL_HEIGHT \ 2 - 1, 0, Y, MODE ) NEXT Y FOR X = 0 TO PXL_WIDTH \ 2 - 1 CALL PXL_LINE( PXL_WIDTH \ 2 - 1, PXL_HEIGHT \ 2 - 1, X, 0, MODE ) NEXT X NEXT I END SUB SUB PXL_INIT '(S)ET..... 0=80 1=40 2=20 3=10 4=08 5=04 6=02 7=01 8=__ '(X)OR..... 0=7F 1=BF 2=DF 3=EF 4=F7 5=FB 6=FD 7=FE 8=__ '(R)IGHT... 0=FF 1=7F 2=3F 3=1F 4=0F 5=07 6=03 7=01 8=__ '(L)EFT.... 0=00 1=80 2=C0 3=E0 4=F0 5=F8 6=FC 7=FE 8=__ '(W)IDTH... 0=__ 1=80 2=C0 3=E0 4=F0 5=F8 6=FC 7=FE 8=FF FOR INDEX = 0 TO 8 IF INDEX <> 8 THEN PXL_MASKS( INDEX ) = 2 ^ ( 7 - INDEX ) IF INDEX <> 8 THEN PXL_MASKX( INDEX ) = 2 ^ ( 7 - INDEX ) XOR $FF IF INDEX <> 8 THEN PXL_MASKR( INDEX ) = 2 ^ ( 8 - INDEX ) - 1 IF INDEX <> 8 THEN PXL_MASKL( INDEX ) = 2 ^ ( 7 - INDEX ) - 1 XOR $FF IF INDEX <> 0 THEN PXL_MASKW( INDEX ) = 2 ^ ( 8 - INDEX ) - 1 XOR $FF NEXT INDEX PXL_ADDR = SYS_CHAR_ADDR + 16 * PXL_CHAR PXL_ADDR_DY = PXL_HEIGHT PXL_SIZE = PXL_WIDTH \ 8 * PXL_ADDR_DY 'IF PXL_BUF_QTY = 0 THEN PXL_CHAR_MAX = PXL_CHAR + PXL_SIZE \ 16 'IF PXL_BUF_QTY = 1 THEN PXL_CHAR_MAX = PXL_CHAR + 2 * PXL_WIDTH \ 8 'IF PXL_BUF_QTY = 2 THEN PXL_CHAR_MAX = PXL_CHAR + 4 * PXL_WIDTH \ 8 PXL_QUOTE = 34 PXL_APOSTRO = 39 PXL_PLUS = 43 PXL_MINUS = 45 PXL_PERIOD = 46 PXL_A = 65 PXL_Z = 90 PXL_BKSLASH = 92 END SUB SUB PXL_FULLSCR_DIR 'PXL LIBRARY FULLSCREEN DIRECT DISPLAY 'BY NATHANIEL R. BABIAK, PE, ED. 25 NOV 2019 'THREE (3) LINES, PXL LIBRARY INPUTS PXL_CHAR = 32 PXL_WIDTH = 160 PXL_HEIGHT = 128 'ONE (1) LINE, REQ'D AFTER ALL PXL LIBRARY INPUTS CALL PXL_INIT 'FOUR (4) LINES, REQ'D FOR DIRECT DISPLAY (NOT BUFFERED) PAL_LO = 6 PAL_HI = 7 COLOR_LO = COLOR( 0, 0 ) COLOR_HI = %00111111 'TWO (2) LINES, REQ'D FOR DIRECT DISPLAY (NOT BUFFERED) PALETTE PAL_LO, COLOR_LO, COLOR_HI, COLOR_LO, COLOR_HI PALETTE PAL_HI, COLOR_LO, COLOR_LO, COLOR_HI, COLOR_HI 'ONE (1) LINE, INITIALIZES A BACKGROUND FOR USE WITH PXL LIBRARY CALL PXL_WINDOW_DIR( 0, 0, PAL_LO, PAL_HI ) END SUB SUB PXL_WINDOW_DIR( CX1, CY1, PAL_LO, PAL_HI ) 'PXL LIBRARY WINDOW DIRECT DISPLAY 'BY NATHANIEL R. BABIAK, PE, ED. 25 NOV 2019 'FIVE (5) LINES, GET CURRENT ATTRIBUTES CELL CX1, CY1, PXL_CHAR ATTRIBUTES = CELL.A( CX1, CY1 ) OLD_PALETTE = ATTRIBUTES AND $07 FLIP_X_BIT = ( ATTRIBUTES AND $08 ) \ $08 FLIP_Y_BIT = ( ATTRIBUTES AND $10 ) \ $10 'TWO (2) LINES CX2 = CX1 + PXL_WIDTH \ 8 - 1 CY2 = CY1 + PXL_HEIGHT \ 8 - 1 'TWELVE (12) LINES, INIT "FOR"'S (S)TEP AND SORT "FOR"'S START(1) AND STOP(2) IF FLIP_X_BIT = 0 THEN SCX = 1 ELSE IF FLIP_X_BIT = 1 THEN SCX = -1 SWAP CX1, CX2 END IF IF FLIP_Y_BIT = 0 THEN SCY = 1 ELSE IF FLIP_Y_BIT = 1 THEN SCY = -1 SWAP CY1, CY2 END IF 'SIXTEEN (16) LINES USE_TOGGLE = FALSE CHARACTER = PXL_CHAR FOR CX = CX1 TO CX2 STEP SCX FOR CY = CY1 TO CY2 STEP SCY IF USE_TOGGLE THEN PAL PAL_HI CELL CX, CY, CHARACTER INC CHARACTER USE_TOGGLE = FALSE ELSE PAL PAL_LO CELL CX, CY, CHARACTER USE_TOGGLE = TRUE END IF NEXT CY NEXT CX 'ONE (1) LINE PAL OLD_PALETTE END SUB SUB LOWRES_NX 'FOR EASE OF READING SYS_CHAR_ADDR = $8000 SYS_BG0_ADDR = $9000 SYS_BG1_ADDR = $9800 SYS_WORK_ADDR = $A000 SYS_PERS_ADDR = $E000 TRUE = -1 FALSE = 0 END SUB