100 REM BASIC Month 6: The Mandelbaum Set 110 REM http://reddit.com/r/RetroBattlestations 120 REM originallay written by FozzTexx 130 REM Turbo-BASIC XL version by /u/papa_robot 200 REM === Initialize variables and constants 210 PI=3.14159265:DIM PT(128):DIM GO(8),CM(8):DIM SZ(23*20),RZ(2),NT(8),NM(8),OM(8) 220 GO(0)=33:GO(1)=138:GO(2)=200 230 CM(0)=1:CM(1)=0:CM(2)=0 240 CM(3)=0:CM(4)=1:CM(5)=0 250 CM(6)=0:CM(7)=0:CM(8)=1 260 GW=GO(2)*GO(2)/GO(1) 270 TH=GO(2)+5:EXEC DLOAD:TH=TH+SZ(1) 280 RZ(0)=319:RZ(1)=189:REM Width & height of screen 290 SX=(RZ(0)-RZ(0)*0.05)/GW:SY=(RZ(1)-RZ(1)*0.07)/TH 300 SK=SX:IF SY1 THEN GOTO 510 570 EXEC O 998 IF PEEK($D01F)<>6 THEN 998: REM wait until START is pressed 999 END 1000 REM === Update current transformation matrix 1010 REM - Input: 3x3 matrix in 1D array NT 1020 REM - Updates 3x3 Matrix in 1D array CM 1025 PROC UPDATE 1030 FOR R=0 TO 2:FOR C=0 TO 2 1040 NM(R*3+C)=0 1050 FOR K=0 TO 2 1060 NM(R*3+C)=NM(R*3+C)+NT(R*3+K)*CM(K*3+C) 1070 NEXT K:NEXT C:NEXT R 1080 FOR K=0 TO 3*3-1:CM(K)=NM(K):NEXT K 1090 ENDPROC 2000 REM === Translate - move origin 2010 REM - Input: X, Y 2020 REM - Updates current transformation matrix in CM 2025 PROC TRANSLATE 2030 NT(0)=1:NT(1)=0:NT(2)=X 2040 NT(3)=0:NT(4)=1:NT(5)=Y 2050 NT(6)=0:NT(7)=0:NT(8)=1 2060 EXEC UPDATE 2070 ENDPROC 2100 REM === Rotate - rotate drawing space 2110 REM - Input: Angle in radians in A 2120 REM - Updates current transformation matrix in CM 2125 PROC ROTATE 2130 NT(0)=COS(A):NT(1)=-SIN(A):NT(2)=0 2140 NT(3)=-NT(1):NT(4)=NT(0):NT(5)=0 2150 NT(6)=0:NT(7)=0:NT(8)=1 2160 EXEC UPDATE 2170 ENDPROC 2200 REM === Scale - modify unit lengths of drawing 2210 REM - Input: X, Y 2220 REM - Updates current transformation matrix in CM 2225 PROC SCALE 2230 NT(0)=X:NT(1)=0:NT(2)=0 2240 NT(3)=0:NT(4)=Y:NT(5)=0 2250 NT(6)=0:NT(7)=0:NT(8)=1 2260 EXEC UPDATE 2270 ENDPROC 2300 REM === Transform single point using current transformation matrix 2310 REM - Input: X, Y 2320 REM - Returns transformed point in X and Y 2325 PROC TRANSFORM 2330 NT(0)=X:NT(1)=Y:NT(2)=1 2340 FOR R=0 TO 2 2350 NM(R)=0 2360 FOR K=0 TO 2 2370 NM(R)=NM(R)+NT(K)*CM(R*3+K) 2380 NEXT K:NEXT R 2390 X=NM(0):Y=NM(1) 2400 ENDPROC 2500 REM === Draw line 2510 REM - Input: X1,Y1 X2,Y2 2515 PROC DRAWL 2520 X=X1:Y=Y1:EXEC TRANSFORM:A1=X:B1=Y 2530 X=X2:Y=Y2:EXEC TRANSFORM:A2=X:B2=Y 2540 PLOT A1,B1:DRAWTO A2,B2 2550 ENDPROC 2600 REM === Load object from DATA 2610 REM - Reads the next object from DATA and leaves size in array SZ 2620 REM and paths in array PT 2625 PROC DLOAD 2630 ZI=0:READ ZX:SZ(0)=ZX:READ ZY:SZ(1)=ZY 2640 READ ZC:PT(ZI)=ZC:ZI=ZI+1 2650 IF ZC=0 THEN GOTO 2695 2660 FOR ZJ=1 TO ZC:READ ZX:READ ZY 2670 PT(ZI)=ZX:ZI=ZI+1:PT(ZI)=ZY:ZI=ZI+1 2680 NEXT ZJ 2690 GOTO 2640 2695 ENDPROC 2700 REM === Draw path 2710 REM - Input: paths to draw in array PT 2715 PROC DRAWP 2720 ZI=0 2730 ZC=PT(ZI):ZI=ZI+1:IF ZC=0 THEN GOTO 2795 2740 X1=PT(ZI):ZI=ZI+1:Y1=PT(ZI):ZI=ZI+1 2750 FOR ZJ=1 TO ZC-1 2760 X2=PT(ZI):ZI=ZI+1:Y2=PT(ZI):ZI=ZI+1 2770 EXEC DRAWL 2780 X1=X2:Y1=Y2:NEXT ZJ 2790 GOTO 2730 2795 ENDPROC 2800 REM == Save current transformation matrix 2810 REM Copies array CM to array OM 2815 PROC MSAVE 2820 FOR I=0 TO 8:OM(I)=CM(I):NEXT I 2830 ENDPROC 2900 REM == Restore transformation matrix 2910 REM Copies array OM to array CM 2915 PROC MRESTORE 2920 FOR I=0 TO 8:CM(I)=OM(I):NEXT I 2930 ENDPROC 3000 REM Mandelbaum arc 3010 REM - Input: Arc center at CX,CY; Start/end radians in SA,EA 3020 REM "If you want to live in a butcher shop, I'm gonna treat you like a piece of meat." 3025 PROC MANDELB 3030 IF (EA0 AND YD<0 THEN A=0:WD=XD:HT=YD 4060 IF XD<0 AND YD<0 THEN A=1.5*PI:HT=XD:WD=YD 4070 IF XD<0 AND YD>0 THEN A=PI:WD=XD:HT=YD 4080 IF XD>0 AND YD>0 THEN A=0.5*PI:HT=XD:WD=YD 4090 WD=ABS(WD):HT=ABS(HT) 4100 NS=WD/NW:SH=INT(NH*NS) 4110 SG=INT((HT+SH-1)/SH):SH=HT/SG 4120 SX=GO(0)/NW:SY=SH/NH 4130 EXEC MSAVE 4140 AX=X1:AY=Y1:X=X1:Y=Y1:EXEC TRANSFORM:OX=X:OY=Y 4150 X=X2:Y=Y2:EXEC TRANSFORM:XD=X-OX:YD=Y-OY 4160 X=0:Y=0:EXEC TRANSFORM 4170 X=-X:Y=-Y:EXEC TRANSLATE:REM Translate 4180 EXEC ROTATE:REM Rotate 4190 X=SX:Y=SY 4200 IF (XD<0 AND YD<0) OR (XD>0 AND YD>0) THEN Y=SX:X=SY 4210 EXEC SCALE:REM Scale 4220 X=OX:Y=OY:EXEC TRANSLATE:REM Translate 4230 REM Walk through PT and draw 4240 FOR SN=0 TO SG-1 4250 ZI=0 4260 ZC=PT(ZI):ZI=ZI+1:IF ZC=0 THEN GOTO 4350 4270 X1=PT(ZI):ZI=ZI+1 4280 Y1=PT(ZI)*(SH-1)/SH-SN*(SH/SY):ZI=ZI+1 4290 FOR ZJ=1 TO ZC-1 4300 X2=PT(ZI):ZI=ZI+1 4310 Y2=PT(ZI)*(SH-1)/SH-SN*(SH/SY):ZI=ZI+1 4320 EXEC DRAWL 4330 X1=X2:Y1=Y2:NEXT ZJ 4340 GOTO 4260 4350 NEXT SN 4360 EXEC MRESTORE 4370 REM Return height to decide if it's time to stop 4380 X=AX:Y=AY+SH:EXEC TRANSFORM 4390 HT=SQR((X-OX)*(X-OX)+(Y-OY)*(Y-OY)) 4400 ENDPROC 4500 REM === G 4505 PROC G 4510 CX=GX:CY=GY-GB:SA=0:EA=PI:EXEC MANDELB 4520 X1=GO(0):Y1=GY-GB:X2=0:Y2=GY+GB:EXEC MANDELBL 4530 CX=GX:CY=GY+GB:SA=PI:EA=0:EXEC MANDELB 4540 X1=GO(1):Y1=GY+GB:X2=GX:Y2=GY+GB-GO(0):EXEC MANDELBL 4550 ENDPROC 4600 REM === O 4605 PROC O 4610 CX=GX+OO:CY=GY-GB:SA=0:EA=PI:EXEC MANDELB 4620 X1=GO(0)+OO:Y1=GY-GB:X2=OO:Y2=GY+GB:EXEC MANDELBL 4630 CX=GX+OO:CY=GY+GB:SA=PI:EA=0:EXEC MANDELB 4640 X1=GO(1)-GO(0)+OO:Y1=GY+GB:X2=GO(1)+OO:Y2=GY-GB:EXEC MANDELBL 4650 ENDPROC 9000 REM "All aboard the pain train." 9010 DATA 39,16,15,3,-16,0,-16,0,-13,3,-13,3,-3,0,-3,0,0,10,0,10,-3,6,-3 9020 DATA 6,-13,10,-13,10,-16,6,-16,3,-16,11,16,-16,12,-16,12,-13,16,-13 9030 DATA 16,0,19,0,19,-13,23,-13,23,-16,19,-16,16,-16,5,25,-16,27,-16 9040 DATA 27,-13,25,-13,25,-16,19,36,-9,33,-10,32,-11,34,-13,36,-12,39 9050 DATA -12,34,-16,30,-14,29,-11,32,-7,35,-6,36,-5,34,-3,32,-4,29,-4 9060 DATA 34,0,38,-1,39,-5,36,-9,0 9070 DATA 53,16,15,23,-13,23,-16,20,-16,16,-16,13,-16,13,-13,16,-13,16 9080 DATA -3,13,-3,13,0,23,0,23,-3,20,-3,20,-13,23,-13,18,53,-13,53,-16 9090 DATA 46,-16,43,-16,43,-13,43,-10,43,-6,43,-3,43,0,53,0,53,-3,46,-3 9100 DATA 46,-6,51,-6,51,-10,46,-10,46,-13,53,-13,11,10,-16,7,-16,3,-16 9110 DATA 0,-16,0,-13,3,-13,3,0,7,0,7,-13,10,-13,10,-16,14,37,-16,33,-9 9120 DATA 29,-16,26,-16,26,0,29,0,29,-10,32,-4,34,-4,37,-10,37,0,40,0,40 9130 DATA -16,37,-16,0 9140 DATA 52,8,5,0,0,0,-8,3,-4,5,-8,5,0,3,10,0,8,-8,6,0,2,7,-4,9,-4,4,11 9150 DATA 0,11,-8,15,0,15,-8,6,18,-8,16,-8,16,0,18,0,20,-4,18,-8,2,23,-4 9160 DATA 21,-4,4,25,-8,21,-8,21,0,25,0,3,31,0,26,0,26,-8,12,32,-4,35,-4 9170 DATA 36,-5,36,-7,35,-8,32,-8,32,0,35,0,35,0,36,-1,36,-3,35,-4,3,41 9180 DATA 0,39,-8,37,0,2,38,-4,40,-4,6,42,-8,42,-1,44,0,45,0,47,-1,47,-8 9190 DATA 5,48,0,48,-8,50,-4,52,-8,52,0,0