'basically whats going on through this program is we have a background, and instead of drawing the background the normal way, we draw each each pixel of it. this uses way to many characters for us to be able to draw it directly to the regular character data region $8000-$8FFF, so instead we draw it on the ram region $A000, which gives us a generous 4 kilobytes of free storage. the background in this code is 128X7, which is 768 characters, so it takes up 14,336 bytes ($3800 in hex), which is almost all of the $4000 bytes available in ram. what exactly happens each frame is outlined below GLOBAL SCBX BIT0=%10000000 BIT1=%01000000 BIT2=%00100000 BIT3=%00010000 BIT4=%00001000 BIT5=%00000100 BIT6=%00000010 BIT7=%00000001 GLOBAL BIT0,BIT1,BIT2,BIT3,BIT4,BIT5,BIT6,BIT7, TRUE, FALSE, CW, CH,BGH,BGW,T TRUE=-1 FALSE=0 GLOBAL V SCX=0 CW=20 CH=6 'initsimplescreen creates a screen that displays all of the characters after 109 in order. this is necessary for the drawing operations. CALL INITSIMPLESCREEN(8) 'this sub draws the background to the drawing area in RAM. for info on how that actually works look at its sub CALL LOADBGMANUALLY(3) GAMEPAD 1 DO 'this is just scrolling controls 'scx stands for scroll-x IF LEFT(0) THEN SCX=SCX-1 IF RIGHT(0) THEN SCX=SCX+1 'loadbuffer copies a PART of the drawing area in RAM to the character map. i use scx CALL LOADBUFFER(INT(SCX/8)) SCROLL 0,SCX MOD 8,0 X=RND(CW*8) Y=RND(CH*8) 'this draws a circle on a random point in the drawing area. the code for all the drawing functions was made by johnywhateva, so i wont talk about it. all you need to know is that CIR draws a circle, LIN draws a line TRI draws a triangle, etcetera. CALL CIR(X,Y,RND*8,RND*2.99+1) WAIT VBL LOOP SUB LOADBGMANUALLY(R) 'this sub is what draws the background onto the drawing area. R=ROM(3) BGW=PEEK(R+2) BGH=PEEK(R+3) CH=BGH-1 CW=BGW-1 R=R+4 B=$A000 J=0 FOR Y=0 TO CH FOR X=0 TO CW CHA=PEEK(R) AT=PEEK(R+1) 'this FOR loop is what draws each character. 'since johnywhateva's drawing code doesn't work with flipped characters, we need to draw the characters flipped in the correct position or else it won't look like the background we made in the background editor. 'bit4 and bit3 of the cell attribute byte tells us how to flip the cell. so "BIT4 AND AT" will equal 1 when we need to flip left to right, and will be zero when we don't. FOR I=0 TO 15 V=PEEK(ROM(2)+CHA*16+I) IF (BIT4 AND AT)>0 THEN 'bitflip reorders the bits. flipping all of the bytes in a characters data mirrors it from left to right CALL BITFLIP(V) END IF 'to mirror a character from up to down we just have to reorder the way we write the bytes. IF (BIT3 AND AT)>0 THEN 'reorder the bytes POKE $A000+J*16+(7+(I>7)*-8-(I MOD 8)),V ELSE 'don't reorder the bytes POKE $A000+J*16+I,V END IF NEXT I B=B+2 R=R+2 INC J NEXT X NEXT Y END SUB SUB INITSIMPLESCREEN(CY) I=109 FOR Y=CY TO CH+CY FOR X=0 TO CW ATTR 0 CELL X,Y,I INC I NEXT X NEXT Y END SUB SUB LOADBUFFER(SCX) 'this part copys a part of the drawing area to the character memory. 'it copies an entire horizontal line of characters one at a time. 'R=$A000 FOR Y=0 TO CH SRC=(Y*BGW+SCX)*16+$A000 DST=(Y*21+109)*16+$8000 COPY SRC,336 TO DST NEXT Y END SUB SUB BITFLIP(V) V=(V AND BIT7)*128-((V AND BIT6)>0)*64-((V AND BIT5)>0)*32-((V AND BIT4)>0)*16-((V AND BIT3)>0)*8-((V AND BIT2)>0)*4-((V AND BIT1)>0)*2-((V AND BIT0)>0) END SUB HLINES: X=RND(CW*8) Y=RND(CH*8) N=RND(60) C=RND(4) CALL HLIN(X,X+N,Y,C) WAIT VBL IF TIMER>T+600 THEN T=TIMER FILL $A000,CW*CW*16,0 GOTO CIRCLES END IF GOTO HLINES CIRCLES: X=RND(CW*8) Y=RND(CH*8) R=RND(50)+1 C=RND(4) CALL CIR(X,Y,R,C) WAIT VBL IF TIMER>T+600 THEN T=TIMER FILL $A000,CW*CW*16,0 GOTO TRIANGLES END IF GOTO CIRCLES TRIANGLES: X1=RND(120) Y1=RND(120) X2=RND(120) Y2=RND(120) X3=RND(120) Y3=RND(120) CALL TRI(X1,Y1,X2,Y2,X3,Y3,RND(4)) WAIT VBL IF TIMER>T+600 THEN T=TIMER FILL $A000,CW*CH*16,0 GOTO LINES END IF GOTO TRIANGLES LINES: INC CW INC CH X=RND*CW*8 Y=RND*CH*8 CALL LIN(X,Y,X+RND(8),Y+RND(8),RND(4)) DEC CH DEC CW RETURN IF TIMER>T+600 THEN T=TIMER FILL $A000,CW*CW*16,0 GOTO PIXELS END IF GOTO LINES PIXELS: CALL PIX(X,Y,C) 'INCREMENT X,Y PIXEL INC X IF X>=CW*8 THEN X=0 INC Y IF Y>=CH*8 THEN Y=0 INC C IF C>3 THEN C=0 END IF END IF 'WAIT VBL IF TIMER>T+600 THEN T=TIMER FILL $A000,CW*CH*16,0 GOTO HLINES END IF GOTO PIXELS SUB PIXCOL(N,B,C) IF N<$A000 OR N>$DFFF THEN EXIT SUB IF C MOD 2 = 1 THEN POKE N,PEEK(N) OR B ELSE POKE N,PEEK(N) AND NOT B END IF IF (C/2) MOD 2 = 1 THEN POKE N+8,PEEK(N+8) OR B ELSE POKE N+8,PEEK(N+8) AND NOT B END IF END SUB SUB PIX(X,Y,C) IF X<0 OR Y<0 OR X>=CW*8 OR Y>=CH*8 THEN EXIT SUB 'X,Y PIXEL CONVERSION B=2^(7-(X MOD 8)) N=$A000+(INT(X/8)*16)+(Y MOD 8)+(INT(Y/8)*(CW*16)) CALL PIXCOL(N,B,C) END SUB SUB LIN(X1,Y1,X2,Y2,C) DX=X2-X1 DY=Y2-Y1 XD=SGN(DX) YD=SGN(DY) IF DY=0 THEN CALL HLIN(X1,X2,Y1,C) ELSE S=DX/ABS(DY) FOR I=0 TO ABS(DY) XL=MIN((I*S)+X1,((I+1)*S)+X1) XM=MAX((I*S)+X1,((I+1)*S)+X1) IF INT(XL)=INT(XM) THEN CALL PIX(XL,Y1+(I*YD),C) ELSE CALL HLIN(XL,XM,Y1+(I*YD),C) END IF NEXT I END IF END SUB SUB TRI(X1,Y1,X2,Y2,X3,Y3,C) 'BOTTOM CORNER IF Y1>=Y2 AND Y1>=Y3 THEN A=1 XB=X1 YB=Y1 ELSE IF Y2>=Y1 AND Y2>=Y3 THEN A=2 XB=X2 YB=Y2 ELSE IF Y3>=Y1 AND Y3>=Y2 THEN A=3 XB=X3 YB=Y3 END IF 'TOP CORNER IF Y1<=Y2 AND Y1<=Y3 THEN B=1 XT=X1 YT=Y1 ELSE IF Y2<=Y1 AND Y2<=Y3 THEN B=2 XT=X2 YT=Y2 ELSE IF Y3<=Y1 AND Y3<=Y2 THEN B=3 XT=X3 YT=Y3 END IF 'MIDDLE CORNER IF A<>1 AND B<>1 THEN XM=X1 YM=Y1 ELSE IF A<>2 AND B<>2 THEN XM=X2 YM=Y2 ELSE IF A<>3 AND B<>3 THEN XM=X3 YM=Y3 END IF 'MIDDLE SIDE SLOPE DX=XB-XT DY=YB-YT IF DY=0 THEN S0=DX ELSE S0=DX/DY END IF 'TOP SIDE DX=XM-XT DY=YM-YT IF DY=0 THEN S1=DX ELSE S1=DX/DY END IF FOR Y=0 TO DY A=MIN((S1*Y)+XT,(S0*Y)+XT) B=MAX((S1*Y)+XT,(S0*Y)+XT) CALL HLIN(A,B,Y+YT,C) NEXT Y 'BOTTOM SIDE DX=XB-XM DY=YB-YM IF DY=0 THEN S1=-DX ELSE S1=-DX/DY END IF S0=-S0 FOR Y=0 TO DY A=MIN((S1*(DY-Y))+XB,(S0*(DY-Y))+XB) B=MAX((S1*(DY-Y))+XB,(S0*(DY-Y))+XB) CALL HLIN(A,B,Y+YM,C) NEXT Y END SUB SUB CIR(X,Y,R,C) FOR I=-R TO R A=SQR((R*R)-(I*I)) CALL HLIN(X-A,X+A,Y+I,C) 'FOR N=-A TO A 'CALL PIX(X+I,Y+N,C) 'NEXT N NEXT I END SUB SUB HLIN(X1,X2,Y,C) BGW=CW+1 'ONLY HORIZONTAL 'SIGNIFICANTLY FASTER THAN LIN() IF X1<0 THEN X1=0 IF X2>=BGW*8 THEN X2=(BGW*8)-1 'LEFT MOST MEMORY LOCATION ML=$A000+(INT(X1/8)*16)+(Y MOD 8)+(INT(Y/8)*(BGW*16)) 'RIGHT MOST MEMORY LOCATION MR=$A000+(INT(X2/8)*16)+(Y MOD 8)+(INT(Y/8)*(BGW*16)) B=0 IF ML=MR THEN B=(2^(7-(X1 MOD 8)))-1 ADD B,-((2^(7-(X2 MOD 8)))-1) CALL PIXCOL(ML,B,C) ELSE 'LEFT MOST B=(2^(7-(X1 MOD 8)))-1 CALL PIXCOL(ML,B,C) 'RIGHT MOST B=(2^(7-(X2 MOD 8)))-1 CALL PIXCOL(MR,NOT B,C) 'IN BETWEEN I=ML+16 WHILE I