'OPTIMIZATIONS '- [DONE] DRAW LINE SEGMENTS INSTEAD OF PIXELS '- [IN PROGRESS] DRAW BLOCKS INSTEAD OF SEGMENTS USING THE FILL COMMAND ' - USES "FILL A,8,C0", WORKS ONLY FOR CENTER BLOCKS (THEY DON'T NEED OVERLAY) ' - IS GOING TO MORE THAN DOUBLE THE SPEED AGAIN ' - BUT IT HAS TO BE INTEGRATED IN EACH SHAPE '- REPEAT A GENERATED SHAPE DOWN (RECTANGLES) 'I GUESS THE HORIZONTAL LINES ARE GOOD FOR FLOOD FILL TOO 'S E T U P 'DEFINE ROM FOR FASTER PIXEL PROCESSING NN=127 DIM GLOBAL LLINE_ROM(NN),RLINE_ROM(NN),PIXEL_ROM(NN),YADDR_ROM(NN),XCELL_ROM(NN) FOR I=0 TO NN 'PREPARE II=MAX(0,MIN(127,I)) III=II MOD 8 'PIXEL SEGMENTS LLINE_ROM(I)= 255 XOR 2^(7-III)-1 RLINE_ROM(I)= 2^(8-III)-1 PIXEL_ROM(I)= 2^(7-III) 'ADDRESSES YADDR_ROM(I)=$8000+(I\8)*256+(I MOD 8) XCELL_ROM(I)=(I\8)*8*2 NEXT I 'DETECT BIT LENGTHS DIM GLOBAL LBIT_LEN(255),RBIT_LEN(255) LL=0 LR=0 FOR V=0 TO 255 CALL RBIT_LENGTH(V,LL) CALL LBIT_LENGTH(V,LR) LBIT_LEN(V)=LL RBIT_LEN(V)=LR NEXT V SUB RBIT_LENGTH(V,L) L=0 IF (V AND %11111111) = 0 THEN 'PRINT "4",BIN$(V,8) L=8 EXIT SUB ELSE IF (V AND %11111110) = 0 THEN 'PRINT "4",BIN$(V,8) L=7 EXIT SUB ELSE IF (V AND %11111100) = 0 THEN 'PRINT "4",BIN$(V,8) L=6 EXIT SUB ELSE IF (V AND %11111000) = 0 THEN 'PRINT "4",BIN$(V,8) L=5 EXIT SUB ELSE IF (V AND %11110000) = 0 THEN 'PRINT "4",BIN$(V,8) L=4 EXIT SUB ELSE IF (V AND %11100000) = 0 THEN 'PRINT "4",BIN$(V,8) L=3 EXIT SUB ELSE IF (V AND %11000000) = 0 THEN 'PRINT "4",BIN$(V,8) L=2 EXIT SUB ELSE IF (V AND %10000000) = 0 THEN 'PRINT "4",BIN$(V,8) L=1 EXIT SUB END IF END SUB SUB LBIT_LENGTH(V,L) L=0 IF (V AND %11111111) = 0 THEN L=8 EXIT SUB ELSE IF (V AND %01111111) = 0 THEN L=7 EXIT SUB ELSE IF (V AND %00111111) = 0 THEN L=6 EXIT SUB ELSE IF (V AND %00011111) = 0 THEN L=5 EXIT SUB ELSE IF (V AND %00001111) = 0 THEN L=4 EXIT SUB ELSE IF (V AND %00000111) = 0 THEN L=3 EXIT SUB ELSE IF (V AND %00000011) = 0 THEN L=2 EXIT SUB ELSE IF (V AND %00000001) = 0 THEN L=1 EXIT SUB END IF END SUB TOUCHSCREEN 'POKE $FF72,80 BG VIEW OFF 1 'ON RASTER CALL RASTERFX SUB RASTERFX SCROLL 0,0,RASTER MOD 4 END SUB CALL VIEW_CHARACTERS(2,0,0,255) 'CALL HLINE(30,20,50,3) 'CALL BAR(97,45,13,90,RND(3)) 'CALL BAR(60,80,10,20,1) 'CALL DIAMOND(50,50,50,1) 'CALL CIRCLE(RND(127),RND(127),RND(63),RND(2)+1) 'CALL CIRCLE(50,50,50,1) 'CALL TRIANGE(RND(127),RND(127),RND(127),RND(127),RND(127),RND(127),RND(2)+1) CALL CIRCLE(50,50,50,1) CALL CIRCLE(50,50,40,0) CALL CIRCLE(70,70,10,1) CALL CIRCLE(60,60,2,1) CALL CIRCLE(40,40,10,1) 'CALL FLOOD_FILL(50,52,2) TOUY=10 DO IF TOUCH AND TOUCH.Y<>TOUY THEN TOUY=TOUCH.Y CALL FLOOD_FILL(TOUCH.X-16,TOUCH.Y,2) END IF WAIT VBL LOOP DO 'TRACE TOUCH.X-80 'CALL BAR(RND(255),RND(255),RND(255),RND(255),RND(3)) 'FOR I=0 TO 27 STEP 10 'CALL BAR(20+I,30+I,40+I,50+I,RND(3)) 'NEXT I 'FOR I=0 TO 27 'CALL HLINE(20+I,0+I,50+I,RND(3)) 'NEXT I 'FOR I=0 TO 256 'CALL HLINE(RND(255),RND(255),RND(255),RND(3)) 'WAIT VBL 'NEXT I 'CALL BAR_FASTER(RND(127),RND(127),RND(127),RND(127),RND(2)+1) 'CALL DIAMOND(RND(127),RND(127),RND(63),RND(2)+1) 'CALL CIRCLE(RND(127),RND(127),RND(62)+1,RND(2)+1) 'CALL TRIANGE(RND(127),RND(127),RND(127),RND(127),RND(127),RND(127),RND(2)+1) 'CALL QUAD(RND(127),RND(127),RND(127),RND(127),RND(127),RND(127),RND(127),RND(127),RND(2)+1) 'WAIT VBL 'CALL TRIANGE(50,60,70,80,TOUCH.X,TOUCH.Y,RND(2)+1) 'CALL TRIANGE(50,60,70,80,TOUCH.X,TOUCH.Y,1) 'WAIT VBL 'FILL $8000,$1000 'WAIT 60 'REPEAT 'WAIT VBL 'UNTIL TAP 'FOR I=0 TO 0 'CALL BAR(RND(127),RND(127),RND(127),RND(127),RND(2)+1) 'NEXT I WAIT VBL 'WAIT 10 'CALL WAIT_AND_CLEAR LOOP SUB WAIT_AND_CLEAR REPEAT WAIT VBL UNTIL TAP FILL $8000,$1000 END SUB 'S U B P R O G R A M S SUB BAR(X1,Y1,X2,Y2,C) C0=C MOD 2 C1=C\2 C0L=C0*255 C1L=C1*255 DY=-(Y2-Y1>0)*2-1 FOR Y=Y1 TO Y2 STEP DY 'CALL HLINE_XOR(X1,Y,X2,C) CALL HLINE_FASTER(X1,Y,X2,C0,C1,C0L,C1L) NEXT Y END SUB SUB BAR_FAST(X0,Y0,X1,Y1,C) 'CONSTANTS: COLORS AND INVERTED %111 C0=C MOD 2 C1=C\2 C0L=C0*255 C1L=C1*255 N7=NOT(7) 'SAFETY: RECTIFY ORDER AND BOUNDARIES IF X0>X1 THEN SWAP X0,X1 IF Y0>Y1 THEN SWAP Y0,Y1 X0=MAX(0,MIN(127,X0)) X1=MAX(0,MIN(127,X1)) Y =MAX(0,MIN(127,Y )) 'PREPARE X: ADDRESSES (LEFT, RIGHT), EDGE PIXEL SEGMENTS A1=XCELL_ROM(X0) A2=XCELL_ROM(X1) N0=RLINE_ROM(X0) N1=LLINE_ROM(X1) 'PREPARE Y: FILL SIZES (TOP, BOTTOM), CELL ADDRESSES (TOP, BOTTOM) S0=8-(Y0 MOD 8) S1=(Y1 MOD 8)+1 YY0=Y0 AND N7 YY1=Y1 AND N7 'IF VERY SLIM IF A1=A2 THEN N=N0 AND N1 FOR Y=Y0 TO Y1 'YADDR_ROM(Y) IS DEFINED AS: "$8000+(Y\8)*256+(Y MOD 8)" CALL OVERLAY2_FASTER(YADDR_ROM(Y)+A1, N,C0,C1) NEXT Y EXIT SUB END IF 'SEGMENTS: VERTICAL LOOP FOR THE LEFT AND RIGHT EDGES FOR Y=Y0 TO Y1 'FOR I0=$8000 TO $9000 STEP 256 'FOR A0=I0 TO I0+7 'A0=$8000+(Y\8)*256+(Y MOD 8) A0=YADDR_ROM(Y) CALL OVERLAY2_FASTER(A0+A1,N0,C0,C1) CALL OVERLAY2_FASTER(A0+A2,N1,C0,C1) 'NEXT A0 'NEXT I0 NEXT Y 'IF VERY FLAT IF YY0=YY1 THEN S=S1+S0-8 YA=YADDR_ROM(Y0) FOR A=A1+16+YA TO A2-16+YA STEP 16 FILL A ,S,C0L FILL A+8,S,C1L NEXT A EXIT SUB END IF 'HORIZONTAL LOOP FOR THE FIELD IN BETWEEN THE EDGES 'DOESN'T NEED OVERLAY AND SEGMENT IS ALWAYS 255 'BOTH BYTES NEED TO BE WRITTEN FOR PROPER OVERWRITE FOR A=A1+16 TO A2-16 STEP 16 'FILL TOP A0=A+YADDR_ROM(Y0) FILL A0 ,S0,C0L FILL A0+8,S0,C1L 'FILL CENTER 'X AND NOT(7) MEANS (X\8)*8 'VERTICAL LOOP FOR THE CENTER FOR Y=YY0+8 TO YY1-8 STEP 8 'A0=A+$8000+(Y\8)*256+(Y MOD 8) A0=A+YADDR_ROM(Y) FILL A0 ,8,C0L FILL A0+8,8,C1L NEXT Y 'FILL BOTTOM A0=A+YADDR_ROM(YY1) FILL A0 ,S1,C0L FILL A0+8,S1,C1L NEXT A 'A0=$8000+(Y\8)*256+(Y MOD 8) 'A0=$8000+Y*32+(Y\8)*8 'A0=$8000+Y+248*(Y\8) 'FOR A0=$8000 TO $9000 STEP 248 'FOR A=A0 TO A0+7 ':) :( HOI BLIJ VERDRIETIG! 'DEBUGGING TOOL: 'PC=1-(C=1) 'CALL PLOT(X0,Y0,PC) 'CALL PLOT(X1,Y1,PC) 'REPEAT 'WAIT VBL 'UNTIL TAP 'EXIT SUB END SUB SUB BAR_FASTER(X0,Y0,X1,Y1,C) 'CONSTANTS: COLORS AND INVERTED %111 C0=C MOD 2 C1=C\2 C0L=C0*255 C1L=C1*255 COPYA=ROM(6+C) 'TRACE 6+C,HEX$(COPYA,4) N7=NOT(7) 'SAFETY: RECTIFY ORDER AND BOUNDARIES IF X0>X1 THEN SWAP X0,X1 IF Y0>Y1 THEN SWAP Y0,Y1 X0=MAX(0,MIN(127,X0)) X1=MAX(0,MIN(127,X1)) Y =MAX(0,MIN(127,Y )) 'PREPARE X: ADDRESSES (LEFT, RIGHT), EDGE PIXEL SEGMENTS A1=XCELL_ROM(X0) A2=XCELL_ROM(X1) N0=RLINE_ROM(X0) N1=LLINE_ROM(X1) 'PREPARE Y: FILL SIZES (TOP, BOTTOM), CELL ADDRESSES (TOP, BOTTOM) S0=8-(Y0 MOD 8) S1=(Y1 MOD 8)+1 YY0=Y0 AND N7 YY1=Y1 AND N7 SSS=(A2 -A1 -32)+16 AAA=A1+16 'IF VERY SLIM IF A1=A2 THEN N=N0 AND N1 FOR Y=Y0 TO Y1 'YADDR_ROM(Y) IS DEFINED AS: "$8000+(Y\8)*256+(Y MOD 8)" CALL OVERLAY2_FASTER(YADDR_ROM(Y)+A1, N,C0,C1) NEXT Y EXIT SUB END IF 'SEGMENTS: VERTICAL LOOP FOR THE LEFT AND RIGHT EDGES 'THIS IS THE BOTTLENECK (50% CPU ON EXIT SUB HERE) FOR Y=Y0 TO Y1 'FOR I0=$8000 TO $9000 STEP 256 'FOR A0=I0 TO I0+7 'A0=$8000+(Y\8)*256+(Y MOD 8) A0=YADDR_ROM(Y) CALL OVERLAY2_FASTER(A0+A1,N0,C0,C1) CALL OVERLAY2_FASTER(A0+A2,N1,C0,C1) 'NEXT A0 'NEXT I0 NEXT Y 'IF VERY FLAT IF YY0=YY1 THEN S=S1+S0-8 YA=YADDR_ROM(Y0) FOR A=A1+16+YA TO A2-16+YA STEP 16 FILL A ,S,C0L FILL A+8,S,C1L NEXT A EXIT SUB END IF 'HORIZONTAL LOOP FOR THE FIELD IN BETWEEN THE EDGES 'DOESN'T NEED OVERLAY AND SEGMENT IS ALWAYS 255 'BOTH BYTES NEED TO BE WRITTEN FOR PROPER OVERWRITE FOR A=A1+16 TO A2-16 STEP 16 'FILL TOP A0=A+YADDR_ROM(Y0) FILL A0 ,S0,C0L FILL A0+8,S0,C1L 'FILL BOTTOM A0=A+YADDR_ROM(YY1) FILL A0 ,S1,C0L FILL A0+8,S1,C1L NEXT A 'FILL CENTER 'VERTICAL LOOP FOR THE CENTER FOR Y=YY0+8 TO YY1-8 STEP 8 A0=AAA+YADDR_ROM(Y) COPY COPYA,SSS TO A0 NEXT Y 'FILL CENTER 'FOR A=A1+16 TO A2-16 STEP 16 'FOR Y=YY0+8 TO YY1-8 STEP 8 'A0=A+YADDR_ROM(Y) 'COPY COPYA,16 TO A0 'NEXT Y 'NEXT A 'A0=$8000+(Y\8)*256+(Y MOD 8) 'A0=$8000+Y*32+(Y\8)*8 'A0=$8000+Y+248*(Y\8) 'FOR A0=$8000 TO $9000 STEP 248 'FOR A=A0 TO A0+7 ':) :( HOI BLIJ VERDRIETIG! 'DEBUGGING TOOL: 'PC=1-(C=1) 'CALL PLOT(X0,Y0,PC) 'CALL PLOT(X1,Y1,PC) 'REPEAT 'WAIT VBL 'UNTIL TAP 'EXIT SUB END SUB SUB DIAMOND(X,Y,R,C) C0=C MOD 2 C1=C\2 C0L=C0*255 C1L=C1*255 FOR I=0 TO R-1 J=R-I CALL HLINE_FASTER(X-I,Y-J,X+I,C0,C1,C0L,C1L) CALL HLINE_FASTER(X-I,Y+J,X+I,C0,C1,C0L,C1L) NEXT I CALL HLINE_FASTER(X-R,Y,X+R,C0,C1,C0L,C1L) END SUB SUB CIRCLE(CX,CY,R,C) C0=C MOD 2 C1=C\2 C0L=C0*255 C1L=C1*255 'R_SQUARED=R*R DR=1/R I=0 FOR Y=1 TO R 'XX=SQR(R_SQUARED-Y*Y) 'IF I>1 OR I<-1 THEN TRACE I A=ASIN(I) XX=INT(COS(A)*R) X1=CX-XX X2=CX+XX CALL HLINE_FASTER(X1,CY+Y,X2,C0,C1,C0L,C1L) CALL HLINE_FASTER(X1,CY-Y,X2,C0,C1,C0L,C1L) I=MIN(I+DR,1) NEXT Y CALL HLINE_FASTER(CX-R,CY,CX+R,C0,C1,C0L,C1L) END SUB 'TRIANGLE SPELLED WRONG DIDN'T CAUSE ERRORS SUB TRIANGE(X0,Y0,X1,Y1,X2,Y2,C) 'OPTIMALIZATION: '- ONE LINE IS ALWAYS ACTIVE '- THE OTHER LINE GETS SWAPPED '- START POINT '- SWAP POINT 'TO DO '- FIX THE SHOOT-OUTS '- MAKE IT CLAMP ' - KEEP ORIGINAL POINTS, JUST EDIT THE LOOP BOUNDARIES '- GET IT IN THE RIGHT ORDER ' - DETECT IT BEFORE THE LOOP ' - SWAP THE TWO X AND THEIR STEEPNESS, AND MEMORIZE THIS EVENT WITH A VARIABLE ' - AT THE END OF THE FIRST LOOP UNSWAP, AND RESWAP '- SO THAT THE LINE'S SAFETY CAN BE REMOVED, SAVING 30% CPU 'A NEW TRIANGLE SUBPROGRAM THAT GENERATES THE ROM VALUES USING THE CURRENT LINEAR METHOD 'IF A0 CAN BE GENERATED THEN A1 AND A2 CAN ALSO BE GENERATED 'X0=MAX(0,MIN(127,X0)) 'X1=MAX(0,MIN(127,X1)) 'X2=MAX(0,MIN(127,X2)) 'Y0=MAX(0,MIN(127,Y0)) 'Y1=MAX(0,MIN(127,Y1)) 'Y2=MAX(0,MIN(127,Y2)) 'X0=MAX(20,MIN(107,X0)) 'X1=MAX(20,MIN(107,X1)) 'X2=MAX(20,MIN(107,X2)) 'Y0=MAX(20,MIN(107,Y0)) 'Y1=MAX(20,MIN(107,Y1)) 'Y2=MAX(20,MIN(107,Y2)) 'SORT IF Y0>Y1 THEN SWAP Y0,Y1 SWAP X0,X1 END IF IF Y1>Y2 THEN SWAP Y1,Y2 SWAP X1,X2 END IF IF Y0>Y1 THEN 'BUG MEMORIAL: THIS WAS COPIED WITHOUT MODIFYING, ALSO IT WAS WRONG BECAUSE Y2 BECAME Y1 SWAP Y0,Y1 SWAP X0,X1 END IF 'PREPARE LINES: HEIGHT DIFFERENCE (DY), 1/(DY/WIDTH DIFFERENCE), START VALUE DY0=Y1-Y0 DY1=Y2-Y1 DY2=Y2-Y0 IF DY0<>0 THEN DD0=(X1-X0)/DY0 ELSE DD0=0 IF DY1<>0 THEN DD2=(X2-X1)/DY1 ELSE DD2=0 IF DY2<>0 THEN DD1=(X2-X0)/DY2 ELSE DD1=0 XX0=X0 XX1=X0 XX2=X1 C0=C MOD 2 C1=C\2 C0L=C0*255 C1L=C1*255 'EXIT SUB: 0.1% CPU 'START 'DRASTIC OPTIMIZATIONS: FOR STEP 2 WITH RASTER (TRIANGLES NEED TO BE Y0=Y0 XOR 1) FOR Y=Y0 TO Y1 ADD XX0,DD0 ADD XX1,DD1 CALL HLINE_FASTER(INT(XX0),Y,INT(XX1),C0,C1,C0L,C1L) NEXT Y 'LINE SWAP FOR Y=Y1 TO Y2 ADD XX1,DD1 ADD XX2,DD2 CALL HLINE_FASTER(INT(XX1),Y,INT(XX2),C0,C1,C0L,C1L) NEXT Y 'CC=MAX(1,(C+1)MOD 3) 'CC=2 'CALL PLOT(X0,Y0,CC) 'CALL PLOT(X1,Y1,CC) 'CALL PLOT(X2,Y2,CC) 'Y = A*X + B 'X = (Y-B)/A 'X = Y/A - B/A 'X0 = 0/A - B/A 'X0 = - B/A 'XN = X0 + N*(1/A) 'B = Y - A*X 'B0=Y0 - (1/DD0)*X0 'XX0=-B0*DD0 'XX0=X0-Y0*DD0 'XX0=(Y-Y0)*DD0 'XX1=(Y-Y1)*DD1 'XX2=(Y-Y2)*DD2 END SUB SUB QUAD(X0,Y0,X1,Y1,X2,Y2,X3,Y3,C) 'OPTIMALIZATION: '- ONE LINE IS ALWAYS ACTIVE '- THE OTHER LINE GETS SWAPPED '- START POINT '- SWAP POINT 'TO DO '- FIX THE SHOOT-OUTS '- MAKE IT CLAMP ' - KEEP ORIGINAL POINTS, JUST EDIT THE LOOP BOUNDARIES '- GET IT IN THE RIGHT ORDER ' - DETECT IT BEFORE THE LOOP ' - SWAP THE TWO X AND THEIR STEEPNESS, AND MEMORIZE THIS EVENT WITH A VARIABLE ' - AT THE END OF THE FIRST LOOP UNSWAP, AND RESWAP '- SO THAT THE LINE'S SAFETY CAN BE REMOVED, SAVING 30% CPU 'A NEW TRIANGLE SUBPROGRAM THAT GENERATES THE ROM VALUES USING THE CURRENT LINEAR METHOD 'IF A0 CAN BE GENERATED THEN A1 AND A2 CAN ALSO BE GENERATED 'X0=MAX(0,MIN(127,X0)) 'X1=MAX(0,MIN(127,X1)) 'X2=MAX(0,MIN(127,X2)) 'Y0=MAX(0,MIN(127,Y0)) 'Y1=MAX(0,MIN(127,Y1)) 'Y2=MAX(0,MIN(127,Y2)) 'X0=MAX(20,MIN(107,X0)) 'X1=MAX(20,MIN(107,X1)) 'X2=MAX(20,MIN(107,X2)) 'Y0=MAX(20,MIN(107,Y0)) 'Y1=MAX(20,MIN(107,Y1)) 'Y2=MAX(20,MIN(107,Y2)) 'SORT IF Y0>Y1 THEN SWAP Y0,Y1 SWAP X0,X1 END IF IF Y1>Y2 THEN SWAP Y1,Y2 SWAP X1,X2 END IF IF Y0>Y1 THEN 'BUG MEMORIAL: THIS WAS COPIED WITHOUT MODIFYING, ALSO IT WAS WRONG BECAUSE Y2 BECAME Y1 SWAP Y0,Y1 SWAP X0,X1 END IF 'PREPARE LINES: HEIGHT DIFFERENCE (DY), 1/(DY/WIDTH DIFFERENCE), START VALUE DY0=Y1-Y0 DY1=Y2-Y1 DY2=Y2-Y0 IF DY0<>0 THEN DD0=(X1-X0)/DY0 ELSE DD0=0 IF DY1<>0 THEN DD2=(X2-X1)/DY1 ELSE DD2=0 IF DY2<>0 THEN DD1=(X2-X0)/DY2 ELSE DD1=0 XX0=X0 XX1=X0 XX2=X1 C0=C MOD 2 C1=C\2 C0L=C0*255 C1L=C1*255 'EXIT SUB: 0.1% CPU 'START 'DRASTIC OPTIMIZATIONS: FOR STEP 2 WITH RASTER (TRIANGLES NEED TO BE Y0=Y0 XOR 1) FOR Y=Y0 TO Y1 ADD XX0,DD0 ADD XX1,DD1 CALL HLINE_FASTER(INT(XX0),Y,INT(XX1),C0,C1,C0L,C1L) NEXT Y 'LINE SWAP FOR Y=Y1 TO Y2 ADD XX1,DD1 ADD XX2,DD2 CALL HLINE_FASTER(INT(XX1),Y,INT(XX2),C0,C1,C0L,C1L) NEXT Y 'CC=MAX(1,(C+1)MOD 3) 'CC=2 'CALL PLOT(X0,Y0,CC) 'CALL PLOT(X1,Y1,CC) 'CALL PLOT(X2,Y2,CC) 'Y = A*X + B 'X = (Y-B)/A 'X = Y/A - B/A 'X0 = 0/A - B/A 'X0 = - B/A 'XN = X0 + N*(1/A) 'B = Y - A*X 'B0=Y0 - (1/DD0)*X0 'XX0=-B0*DD0 'XX0=X0-Y0*DD0 'XX0=(Y-Y0)*DD0 'XX1=(Y-Y1)*DD1 'XX2=(Y-Y2)*DD2 'DEBUGGING TOOL: PC=1-(C=1) CALL PLOT(X0,Y0,PC) CALL PLOT(X1,Y1,PC) CALL PLOT(X2,Y2,PC) CALL PLOT(X3,Y3,PC) REPEAT WAIT VBL UNTIL TAP 'EXIT SUB END SUB SUB POLYGON(X_(),Y_(),C) S= MIN(UBOUND(X_), UBOUND(Y_)) 'DON'T SORT VERTICES, THEY HAVE TO BE IN A VERY SPECIFIC ORDER ANYWAYS 'DON'T CALL SPACESORT(VALUES(),INDEX()) 'FIND THE TOP VERTEX AND USE IT AS THE STARTING POINT FOR THE TWO LINES 'SETUP THE ONE AFTER AND THE ONE BEFORE AS THE TWO LINE END POINTS 'LOOP UNTIL THE SHORTEST Y ENDS 'RECTIFY THE POSITION TO BE EXACTLY THE PREVIOUS END POINT FOR A CLEANER SHAPE 'SET THE TARGET TO BE THE NEXT CONNECTED POINT 'CONTINUE THE LOOP UNTIL THE NEXT Y ENDS 'IF THE NEXT POINT WAS UPWARDS THEN IT HAS TO PUSH EVERYTHING ASIDE TO STACK MEMORY '- MAYBE USING A NESTED FUNCTION 'IT WOULD THEN LOOP TO FIND THE HIGHEST POINT AND RESTART FROM THERE 'UNTIL IT REACHES THE PREVIOUS LAST Y POINT THEN IT WOULD POP THE STACK AND CONTINUE END SUB SUB FLOOD_FILL(XX,YY,C) C0=C MOD 2 C1=C\2 C0L=C0*255 C1L=C1*255 X=XX Y=YY 'IT SCANS THE X-ZONE FOR NEW X-ZONES RIGHTAWAY 'AND MEMORIZES ONE SET OF COORDINATES AND A DIRECTION PER NEWLY DETECTED ZONE FOR Y=YY TO YY+40*0 'CALL PLOT(X,Y,3) 'EXIT SUB 'CALL HLINE_FASTER(X0,Y,X1,C0,C1,C0L,C1L) '(X0,Y,X1,C0,C1,C0L,C1L) 'SAFETY: RECTIFY ORDER AND BOUNDARIES 'EXIT SUB: 15% CPU 'IF X0>X1 THEN SWAP X0,X1 'EXIT SUB: 19% CPU 'X0=MAX(0,MIN(127,X0)) 'X1=MAX(0,MIN(127,X1)) X =MAX(0,MIN(127,X )) 'Y =MAX(0,MIN(127,Y )) 'PREPARE: ADDRESSES (GENERAL, LEFT, RIGHT), EDGE PIXEL SEGMENTS A0=YADDR_ROM(Y) A=A0+XCELL_ROM(X) 'A1=A0+XCELL_ROM(X0) 'A2=A0+XCELL_ROM(X1) 'N0=RLINE_ROM(X0) 'N1=LLINE_ROM(X1) 'THIS MOVES THE X TO A NEIGHBORING FULL SEGMENT IF AVAILABLE, TOTALLY DIDN'T TAKE HOURS... NN=PIXEL_ROM(X) CC=(PEEK(A) AND NN)\NN XXX=XX AND (NOT 7) NOTHIN=0 IF NN<>255 THEN 'ADD XXX,-8 LL=RBIT_LEN(PEEK(A)) LR=LBIT_LEN(PEEK(A)) XM=X MOD 8 LLL=LBIT_LEN(PEEK(A0+XCELL_ROM(MIN(127,X+8)))) RRR=RBIT_LEN(PEEK(A0+XCELL_ROM(MAX(0 ,X-8)))) 'TRACE LR=0 , XM>LL , LLL=8 IF LL=8 AND LR=8 THEN 'TRACE "CENTER" ELSE IF LR=0 AND (XM>LL OR -1) AND LLL=8 THEN ADD XXX,8 'TRACE "RIGHT" ELSE IF LL=0 AND (XM0 THEN NOTHIN = 1 IF LR<>0 THEN NOTHIN = 2 'TRACE "NOTHIN",TIMER END IF 'TRACE XM,LL,LR,LR=0,LL=0,LLL,RRR 'LL=(7+RBIT_LEN(PEEK(A))) MOD 8 'LR=(7+LBIT_LEN(PEEK(A))) MOD 8 'TRACE BIN$(PEEK(A),8) 'TRACE XM,LL,"-",LR,LL>XM,LR>XM 'IF LL<=XM THEN 'ADD XXX,8 'ELSE 'IF LR<=XM THEN 'ADD XXX,-8 'ELSE 'AREA IS SMALLER THAN A CELL 'END IF END IF 'TRACE CC 'X=XX AND (NOT 7) IF NOT(NOTHIN) THEN FOR D=-8 TO 8 STEP 16 X=XXX X =MAX(0,MIN(127,X )) DO A=A0+XCELL_ROM(X) V=PEEK(A) 'TRACE BIN$(V,8),HEX$(A,4),X IF V<>0 THEN EXIT POKE(A+8),255 'POKE(A),C0L ADD X,D IF X>127 OR X<0 THEN EXIT LOOP IF D=-8 THEN XL=X AL=A ELSE XR=X AR=A END IF NEXT D ELSE AL=A AR=A XL=X XR=X END IF LL=(8-RBIT_LEN(PEEK(AL))) MOD 8 LR=(7+LBIT_LEN(PEEK(AR))) MOD 8 'TRACE LR 'LL=0 'LR=0 'LL=3 'LR=2 ADD XL, LL ADD XR,-LR N0=RLINE_ROM(LL) N1=LLINE_ROM(LR) 'TRACE "" 'TRACE "" 'TRACE LL,BIN$(N0,8),BIN$(PEEK(AL),8) 'TRACE LR,BIN$(N1,8),BIN$(PEEK(AR),8) 'SEGMENTS: LEFT, RIGHT IF NOTHIN THEN 'TRACE STR$(LL)+STR$(LR),ABS(AL=AR),BIN$(255 XOR PEEK(AL),8) 'BIN$(N0,8),BIN$(N1,8) 'BOTH N0 AND N1 NEED THE OTHER SIDE TO BE OPEN, THAT AIN'T HAPPENING HERE, 'IT TURNS OUT... IT'S REALLY COMPLICATED, FLOOD FILL LOGIC HAS TO BE DONE BITWISELY 'SO I TEMPORARILY INVERTED THE PIXELS: IT WILL NOW BE ABLE TO PASS THROUGH ISOLATIONS 'CALL OVERLAY2_FASTER(AL,N0 AND N1,C0,C1) CALL OVERLAY2_FASTER(AL,255 XOR PEEK(AL),C0,C1) 'TRACE NOTHIN IF NOTHIN=1 THEN AA=A0+XCELL_ROM(MIN(127,X+8)) CALL OVERLAY2_FASTER(AA,255 XOR PEEK(AA),C0,C1) TRACE "ONE" ELSE IF NOTHIN=2 THEN AA=A0+XCELL_ROM(MAX(0,X-8)) CALL OVERLAY2_FASTER(AA,255 XOR PEEK(AA),C0,C1) END IF ELSE IF LL<>0 THEN CALL OVERLAY2_FASTER(AL,N0,C0,C1) IF LR<>7 THEN CALL OVERLAY2_FASTER(AR,N1,C0,C1) END IF 'LBIT_LEN(I),RBIT_LEN(I) 'TRACE "END" 'IF A1=A2 THEN 'CALL OVERLAY2_FASTER(A1, N0 AND N1, C0,C1) 'EXIT SUB 'END IF 'LINE: ADDRESS, DRAW (DOESN'T NEED OVERLAY AND SEGMENT IS ALWAYS 255) 'BOTH BYTES NEED TO BE WRITTEN FOR PROPER OVERWRITE 'FOR A=A1+16 TO A2-16 STEP 16 'POKE A ,C0L 'POKE A+8,C1L 'NEXT A NEXT Y 'FIND LEFTMOST AND RIGHTMOST COLOR CHANGES 'DRAW A SEGMENT 'WRITE THE FOUND X ZONE AS A CHECK-ZONE TO THE QUEUE/STACK FOR THE SPACE ABOVE AND BELOW 'LOOP THROUGH THE QUEUE/STACK ' LOOP THROUGH THE X ZONE TO CHECK THE FOR COLOR CHANGES ' IN FOUND CLOSED ZONES SEGMENTS WILL BE DRAWN ' AT THE EDGES OF THE ZONES IT'LL SEARCH FOR THE END IF IT ISN'T ENDED ALREADY ' THIS WIDTH IS THE NEW X ZONE ' 'NOPE: IT'LL CHOOSE FROM THE ITEMS IN THE QUEUE/STACK TO GO UPWARDS FIRST 'NOPE: AND ONCE ALL HAVE REACHED THE TOP IT'LL FOLLOW THE QUEUE/STACK AND GO DOWNWARDS 'IT'LL FIND AND MERGE/CUT-OFF OVERLAPPING SEGMENTS IN THE QUEUE/STACK 'HLINE FLOODFILL FROM ONE POINT, GENERATES TWO ENDPOINTS 'FOR THE ENDPOINTS THAT ARE INSIDE THE X ZONE IT'LL RUN A NOT DRAWING HLINE FLOODFILL ' TO FIND A POINT TO RUN ANOTHER NORMAL HLINE FLOODFILL 'IT'LL WRITE UNHANDLED X-ZONES DOWN, OPTIMIZATIONS CAN BE DONE LATER 'UNHANDLED X-ZONES: '- THERES ONE BELOW THE FIRST LINE '- WHENEVER IT GETS INTERRUPTED ALL BUT ONE ARE ADDED TO THE LIST '- WHENEVER AN X-ZONE GROWS BY TWO OR MORE THE EDGES BELOW WILL BE ADDED AS ZONES 'THE LIST STORES (X0,X1,Y,DIRECTION) FOR EACH ZONE 'PROBLEM: THE X-ZONE SHOULD SPLIT WHEN INTERRUPTED OTHERWISE IT'LL FILL ISOLATED BITS END SUB SUB SPACESORT(VALUES(),INDEX()) U=UBOUND(INDEX) FOR I=0 TO UBOUND(VALUES) V0=VALUES(I) FOR K=I-1 TO 0 STEP -1 IF V0>VALUES(INDEX(K)) THEN EXIT INDEX(MIN(K+1,U))=INDEX(K) NEXT K INC K INDEX(MIN(K+1,U))=INDEX(K) INDEX(K)=I TRACE K NEXT I END SUB SUB OVERLAY2(A0,C0,C1) A1=A0+8 M=255 XOR (C0 OR C1) POKE A0,(PEEK(A0) AND M) OR C0 POKE A1,(PEEK(A1) AND M) OR C1 END SUB SUB OVERLAY2_FASTER(A0,N,C0,C1) A1=A0+8 M=255 XOR N POKE A0,(PEEK(A0) AND M) OR C0*N POKE A1,(PEEK(A1) AND M) OR C1*N END SUB SUB XOR_MIX(A0,C0,C1) A1=A0+8 B0=PEEK(A0) B1=PEEK(A1) 'M=255 XOR (C0 OR C1) 'M=255 'POKE A0,(B0 AND M) XOR C0 'POKE A1,(B1 AND M) XOR C1 POKE A0,B0 XOR C0 POKE A1,B1 XOR C1 END SUB SUB PLOT(X,Y,C) A=$8000+(Y\8)*256+(X\8)*16+(Y MOD 8) N=2^(7-(X MOD 8)) 'IF C MOD 2 THEN POKE A ,PEEK(A ) OR N 'IF C\2 THEN POKE A+8,PEEK(A+8) OR N C0=N*(C MOD 2 ) C1=N*(C\2) CALL OVERLAY2(A,C0,C1) 'POKE A ,PEEK(A ) OR (2^N * C MOD 2) 'POKE A+8,PEEK(A+8) OR (2^N * C\2) END SUB SUB PREPARE_HLINE_FASTER(C,C0,C1,C0L,C1L) C0=C MOD 2 C1=C\2 C0L=C0*255 C1L=C1*255 END SUB SUB HLINE(X0,Y,X1,C) 'SAFETY: RECTIFY ORDER AND BOUNDARIES IF X0>X1 THEN SWAP X0,X1 X0=MAX(0,MIN(127,X0)) X1=MAX(0,MIN(127,X1)) Y =MAX(0,MIN(127,Y )) 'PREPARE: COLOR, 8-PIXEL SEGMENT, ADDRESS, QUANTIZED COORDINATES 'EXIT SUB: 30% CPU C0=C MOD 2 C1=C\2 C0L=C0*255 C1L=C1*255 A0=$8000+(Y\8)*256+(Y MOD 8) X0Q=(X0\8)*8 X1Q=(X1\8)*8 'EXIT SUB: 60% CPU IF X0Q=X1Q THEN A=$8000+(Y\8)*256+X0Q*2+(Y MOD 8) N0=RLINE_ROM(X0 MOD 8) N1=LLINE_ROM(X1 MOD 8) N=N0 AND N1 'N=N0 CALL OVERLAY2(A,N*C0,N*C1) EXIT SUB END IF 'LEFT SEGMENT: ADDRESS, BINARY LINE, DRAW A=A0+X0Q*2 N=RLINE_ROM(X0 MOD 8) CALL OVERLAY2(A,N*C0,N*C1) 'LINE: ADDRESS, DRAW (DOESN'T NEED OVERLAY AND SEGMENT IS ALWAYS 255) FOR X=X0Q+8 TO X1-8 STEP 8 A=A0+X*2 POKE A ,C0L POKE A+8,C1L NEXT X 'RIGHT SEGMENT A=A0+X1Q*2 N=LLINE_ROM(X1 MOD 8) CALL OVERLAY2(A,N*C0,N*C1) 'REQUIRED ROM DEFINITIONS: 'RLINE_ROM(I MOD 8) = 2^(8-(I MOD 8))-1 'LLINE_ROM(I MOD 8) = 255 XOR 2^(7-(I MOD 8))-1 'BUG MEMORIAL: (X0\8)*8 INSTEAD OF X0, FIRST CASE WAS SHOVED UNDER THE RUG BY OFFSETS 'DEBUGGING TOOL: 'CALL PLOT(X0,Y,3) 'CALL PLOT(X1,Y,3) END SUB SUB HLINE_FASTER(X0,Y,X1,C0,C1,C0L,C1L) 'SAFETY: RECTIFY ORDER AND BOUNDARIES 'EXIT SUB: 15% CPU IF X0>X1 THEN SWAP X0,X1 'EXIT SUB: 19% CPU X0=MAX(0,MIN(127,X0)) X1=MAX(0,MIN(127,X1)) Y =MAX(0,MIN(127,Y )) 'EXIT SUB: 30% CPU 'PREPARE: ADDRESSES (GENERAL, LEFT, RIGHT), EDGE PIXEL SEGMENTS A0=YADDR_ROM(Y) A1=A0+XCELL_ROM(X0) A2=A0+XCELL_ROM(X1) 'EXIT SUB: 42% CPU N0=RLINE_ROM(X0) N1=LLINE_ROM(X1) 'EXIT SUB: 50% CPU IF A1=A2 THEN CALL OVERLAY2_FASTER(A1, N0 AND N1, C0,C1) EXIT SUB END IF 'SEGMENTS: LEFT, RIGHT CALL OVERLAY2_FASTER(A1,N0,C0,C1) CALL OVERLAY2_FASTER(A2,N1,C0,C1) 'EXIT SUB: 100% CPU 'LINE: ADDRESS, DRAW (DOESN'T NEED OVERLAY AND SEGMENT IS ALWAYS 255) 'BOTH BYTES NEED TO BE WRITTEN FOR PROPER OVERWRITE FOR A=A1+16 TO A2-16 STEP 16 POKE A ,C0L POKE A+8,C1L NEXT A 'REQUIRED ROM DEFINITIONS: 'RLINE_ROM(I MOD 8) = 2^(8-(I MOD 8))-1 'LLINE_ROM(I MOD 8) = 255 XOR 2^(7-(I MOD 8))-1 'BUG MEMORIAL: X0 INSTEAD OF (X0\8)*8, FIRST CASE WAS SHOVED UNDER THE RUG BY OFFSETS 'DEBUGGING TOOL: 'CALL PLOT(X0,Y,3) 'CALL PLOT(X1,Y,3) END SUB 'HLINE_QUEUE ' DRAW THE EDGE AND RECORD THE SHAPE AND FILL SHAPES WHEN READY ' CELL Y IS ALREADY KNOWN (STILL UP TO DATE) ' RECORDING: ' - LEFTMOST CELL X ' - RIGHTMOST CELL X ' - LEFTMOST CELL X OF CONSTANT BLOCK ' - RIGHTMOST CELL X OF CONSTANT BLOCK ' - START HEIGHT FOR EACH CELL ' - STOP HEIGHT FOR EACH CELL ' EVERY 8 LINES IT'S FILL TIME 'NEW BAR DRAWING SUB '- IS A MODIFICATION OF HLINE ' - PREPARATIONS (NOW IT DOESN'T MATTER WHEN THE EDGES ARE DRAWN ' - LOOP FOR Y ' - DRAW EDGES ' EXIT SUB NOT ALLOWED ' - LOOP FOR X ' - IF VERY FLAT: FILL FLAT, EXIT SUB ' - FILL TOP ' - FILL BOTTOM ' - LOOP FOR Y, =(Y/8)*8 (Y AND NOT(7)) STEP 8 ' - FILL A,8,V 'MERGE THE LOOPS SOMEHOW 'ALTERNATIVE TRIANGLE DRAWING METHODS 'CHARACTER THAT HAS A MINIATURE TRIANGLE (SAME STEEPNESSES) 'SPRITES WITH THAT CHARACTER FILL THE SHAPE OF A BIG TRIANGLE 'TRIANGLES DON'T FIT VERY WELL ON TRIANGLES WITHOUT ROTATING SUB HLINE_XOR(X0,Y,X1,C) IF X0>X1 THEN SWAP X0,X1 X0=MAX(0,MIN(127,X0)) X1=MAX(0,MIN(127,X1)) Y =MAX(0,MIN(127,Y )) 'PREPARE: COLOR, 8-PIXEL SEGMENT, ADDRESS, QUANTIZED COORDINATES C0=C MOD 2 C1=C\2 C0L=C0*255 C1L=C1*255 A0=$8000+(Y\8)*256+(Y MOD 8) X0Q=(X0\8)*8 X1Q=(X1\8)*8 IF X0Q=X1Q THEN A=$8000+(Y\8)*256+X0Q*2+(Y MOD 8) N0=RLINE_ROM(X0 MOD 8) N1=LLINE_ROM(X1 MOD 8) N=N0 AND N1 'N=N0 CALL XOR_MIX(A,N*C0,N*C1) EXIT SUB END IF 'LEFT SEGMENT: ADDRESS, BINARY LINE, DRAW A=A0+X0Q*2 N=RLINE_ROM(X0 MOD 8) CALL XOR_MIX(A,N*C0,N*C1) 'LINE: ADDRESS, DRAW (DOESN'T NEED OVERLAY AND SEGMENT IS ALWAYS 255) FOR X=X0Q+8 TO X1-8 STEP 8 A=A0+X*2 'POKE A ,C0L 'POKE A+8,C1L CALL XOR_MIX(A,C0L,C1L) NEXT X 'RIGHT SEGMENT A=A0+X1Q*2 N=LLINE_ROM(X1 MOD 8) CALL XOR_MIX(A,N*C0,N*C1) 'REQUIRED ROM DEFINITIONS: 'RLINE_ROM(I MOD 8) = 2^(8-(I MOD 8))-1 'LLINE_ROM(I MOD 8) = 255 XOR 2^(7-(I MOD 8))-1 'BUG MEMORIAL: (X0\8)*8 INSTEAD OF X0, FIRST CASE WAS SHOVED UNDER THE RUG BY OFFSETS 'DEBUGGING TOOL: 'CALL PLOT(X0,Y,3) 'CALL PLOT(X1,Y,3) END SUB SUB HLINE_ORIGINAL(X0,Y,X1,C) 'SPLIT COLOR VALUE C0=C MOD 2 C1=C\2 'PREPARE ADDRESS A0=$8000+(Y\8)*256+(Y MOD 8)-8 'LEFT SEGMENT X=X0 A=A0+X*2 'N=2^(8-(X MOD 8))-1 N=RLINE_ROM(X MOD 8) CALL XOR_MIX(A,N*C0,N*C1) 'LINE (DOESN'T NEED OVERLAY OR SEGMENT GENERATION) FOR X=X0+8 TO X1 STEP 8 A=A0+X*2 POKE A ,255*C0 POKE A+8,255*C1 NEXT X 'RIGHT SEGMENT A=A0+X*2 X=X1 'N=255 XOR 2^(7-(X MOD 8))-1 N=LLINE_ROM(X MOD 8) CALL XOR_MIX(A,N*C0,N*C1) END SUB SUB VIEW_CHARACTERS(X,Y,C0,C1) CY0=C0\16 CY1=C1\16 CX0=C0 MOD 16 CX1=C1 MOD 16 FOR IY=CY0 TO CY1 FOR IX=0-(IY=CY0)*CX0 TO 15-(IY=CY1)*(CX1-15) CELL X+IX,Y+IY-CY0,IX+IY*16 NEXT IX NEXT IY END SUB #0:BYE BYE DEFAULT FONT 00 #1:MAIN PALETTES 002B160100383400003C0C00003F3C00 003F2A15003F2A15003F2A15003F2A15 #2:MAIN CHARACTERS 00000000000000000000000000000000 55110101000000005511010100000000 55110100000000005511010000000000 55110101010000005511010101000000 55110100000000005511010000000000 55110101000000005511010100000000 55110100000000005511010000000000 55110101010100005511010101010000 55110100000000005511010000000000 55110101000000005511010100000000 55110100000000005511010000000000 55110101010000005511010101000000 55110100000000005511010000000000 55110101000000005511010100000000 55110100000000005511010000000000 55110101010101005511010101010100 #6:ROM COLOR 0 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 #7:ROM COLOR 1 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 #8:ROM COLOR 2 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF #9:ROM COLOR 3 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF