À guisa de (falei bonito agora, hein?) continuação do post sobre cartões SMS em mainframes, Ken Shirriff ficou sabendo que havia um IBM 1401 funcional no Computer History Museum e lá foi-se ele pra brincar com a criança. Brincar do que? Ora, de fazer um programa para imprimir o Conjunto de Mandelbrot. Em que linguagem? Assembler em cartões perfurados, claro, porque linguagem de alto nível, monitor e teclado são para os fracos.
Mas calma que a história não acaba por aí…
Na discussão que se seguiu no Ycombinator, o usuário de codinome fractallyte narra uma aventura mandelbrótica similar, agora com um Commodore 64 e uma impressora matricial Epson RX80, ocorrida em 1986. E o/a camarada ainda tem os printouts!
Outro fractaleiro militante e juramentado, Dave LeCompte, também entrou na festa com uma rotina em Assembler 6502 para o Apple II:
E a festa não tem hora pra acabar. Só não vale dançar homem com homem nem mulher com m… peraí, o que estou dizendo, estamos no século XXI, vale isso também! Vai te catar, Tim Maia.
Contribuição, digo, contribuições de última hora do Giovanni
A primeira contribuição é um código bem singelo e divertido para o MSX2 e posteriores:
10 COLOR 15,0,0:SCREEN 8-4*(PEEK(&H2D)>1) 15 _TURBOON 20 FOR X%=0 TO 255 25 FOR Y%=0 TO 211 30 CA!=X%^3 35 CB!=Y%^2*X% 40 CC!=CA!+CB! 45 A%=(CC!/500)AND&HF8 50 PSET (X%,Y%),A% 55 NEXT Y%,X% 60 _TURBOOFF 65 GOTO 65
Em computadores MSX2 ele utilizará o modo de 256 cores (SCREEN 8) e nos posteriores apenas os 32 tons de cinza do modo de 12 mil cores (SCREEN 12).
E não se esqueçam de carregar o MSX Turbo BASIC (ou comente as linhas 15 e 60 e depois nos conte quanto tempo demora para finalizar). Este programa é uma adaptação dos códigos para desenhar fractais disponíveis na página do emulador Hi65, do Commodore 65.
A outra é para destruir de vez a produtividade das pessoas com exemplos de código em Applesoft BASIC, assembly de Z80 e até mesmo MySQL!
Mais uma contribuição de última hora!
É que eu queria colocar um de Mandelbrot, caramba! Mas os códigos que eu achava estavam se comportando de forma estranha, daí fundi a versão em Applesoft BASIC com a paleta da versão do C65 e pronto!
100 COLOR 15,0,0:SCREEN 5 105 FOR I%=1 TO 15:READ R%,G%,B%:COLOR=(I%,R%,G%,B%):NEXT I% 110 _TURBO ON 115 XC=-.5:YC=0:S=2:XR=S*4/3:YR=S 120 X0=XC-(XR/2):X1=XC+(XR/2) 125 Y0=YX-(YR/2):Y1=YX-(YR/2) 130 XM=XR/255:YM=YR/211:IT%=20 135 FOR YS%=0 TO 211:FOR XS%=0 TO 255 140 X=XS%*XM+X0:Y=YS%*YM+Y0 145 ZX=0:ZY=0:XX=0:YY=0:I%=0 150 I%=I%+1:IF I%>IT% THEN 170 155 ZY=2*ZX*ZY+Y:ZX=XX-YY+X 160 XX=ZX^2:YY=ZY^2:C%=IT%-I% 165 IF XX+YY>=4 GOTO 170 ELSE 150 170 C%=C% AND 15:PSET(XS%,YS%),C% 175 NEXT XS%,YS% 180 _TURBO OFF 185 BEEP 190 GOTO 190 195 DATA 1,0,1,2,0,2,4,0,4,5,0,5,7,0,7,7,0,6,7,0,5,7,0,3 200 DATA 7,0,2,7,0,0,7,1,0,7,2,0,7,4,0,7,5,0,7,7,0
Esta versão é em 16 cores, o do C65 usava 48 cores (como fiz? Média Aritmética!) e o resultado é assim:
Claro, após 5 minuto de iterações (num Turbo R com Turbo BASIC e em modo R800).
Muito legal os efeitos, vou testar no meu XV para ver como ficam…
Quer algo pra testar num MSX1?
100 COLOR 15,0,0:SCREEN 2
105 _TURBO ON
110 XC=-.5:YC=0:S=2:XR=S*4/3:YR=S
115 X0=XC-(XR/2):X1=XC+(XR/2)
120 Y0=YX-(YR/2):Y1=YX-(YR/2)
125 XM=XR/127:YM=YR/95:IT%=20
130 FOR YS%=0 TO 95:FOR XS%=0 TO 127
135 X=XS%*XM+X0:Y=YS%*YM+Y0
140 ZX=0:ZY=0:XX=0:YY=0:I%=0
145 I%=I%+1:IF I%>IT% THEN 165
150 ZY=2*ZX*ZY+Y:ZX=XX-YY+X
155 XX=ZX^2:YY=ZY^2:C%=IT%-I%
160 IF XX+YY>=4 GOTO 165 ELSE 145
165 C%=C% AND 3
170 IF C%=1 THEN PSET(2*XS%,2*YS%),15
175 IF C%=2 THEN LINE(2*XS%,2*YS%)-STEP(1,1),15
180 IF C%=3 THEN LINE(2*XS%,2*YS%)-STEP(1,1),15,BF
185 NEXT XS%,YS%
190 _TURBO OFF
195 BEEP
200 GOTO 200
Acrescentei o Mandelbrot para MSX e quem quiser rodar o programa em um MSX2/MSX2+ em modo Z80 e aconselho uma leve subversão:
135 FOR YS%=0 TO 105:FOR XS%=0 TO 255
170 C%=C% AND 15:PSET(XS%,YS%),C%:PSET(XS%,211-YS%),C%
Como o fractal é horizontalmente simétrico basta desenhar só a primeira metade e copiar na parte de baixo. 🙂
Haha, queria ter deixado um Mandelbrot de contribuição aqui. Cheguei tarde! Parabéns, ficou mutcho bunitchim. =)
Publique assim mesmo, formas diferentes de fazer a mesma coisa são sempre bem vindas
Confesso que eu queria mesmo era fazer o Mandelbrot em SCR7 com entrelaçado, deixando o treco em 512×424@16c — Atualização… Eu fiz 🙂
Pois, finalmente depois de dez mil anos, fiz um Mandelbrot. Não tem nada otimizado porque nem sei por onde começar, fiz o programa baseado no algoritmo JavaScript do Rosetta Code (principalmente porque as cores ficam bonitas). Bem, para ser honesto eu poderia fazer a simetria vertical, mas deu preguiça. =P Depois vou tentar fazer uma versão usando interlace. 😉 Cadê o seu Mandelbrot em SCREEN 7 com interlace? =D
10 COLOR,0,0:SCREEN 8
20 _TURBO ON
30 W=255:H=211:XL=-2:XH=1:YL=-1:YH=1:IT=1000
40 FOR IX=0 TO W:FOR IY=0 TO H
50 X=XL+(XH-XL)*IX/W:Y=YL+(YH-YL)*IY/H
60 CX=X:CY=Y:MI=IT
70 MX=0:MY=0:XX=0:YY=0:XY=0
80 I=0
90 XY=MX*MY:XX=MX*MX:YY=MY*MY
100 MX=XX-YY+CX:MY=XY+XY+CY
110 I=I+1
120 IF I<MI AND XX+YY<=4 GOTO 90
130 IF I=IT THEN CR=0:CG=0:CB=0:GOTO 180
140 C=3*LOG(I)/LOG(IT-1)
150 IF C<1 THEN CG=INT(7*C)*4:CR=0:CB=0
160 IF C=1 THEN CG=28:CR=INT(7*(C-1))*32:CB=0
170 IF C>=2 THEN CG=224:CR=28:CB=INT(3*(C-2))
180 PSET(IX,IY),CR+CG+CB
190 NEXT IY:NEXT IX
200 _TURBO OFF
210 GOTO 210
Pronto, fiz uma nova versão do Mandelbrot, e desta vez roda muito mais rápido e funciona na SCREEN 7 com interlace. No início você escolhe um entre quatro presets para ver áreas diferentes do fractal. Não usa o truque da simetria porque nem todas as visualizações são centradas no eixo Y. Apesar de estar na SCREEN 7 que tem menos cores do que a SCREEN 8, refiz o cálculo de cor e ele acaba mostrando mais cores do que o algoritmo anterior. Depois que o gráfico fica pronto ele carrega uma das paletas, e você pode pressionar uma tecla para alternar entre qualquer uma das três paletas disponíveis. É facílimo modificar para colocar mais paletas. Também é fácil criar mais presets:
200 CLEAR 200,&HD800:COLOR15,1,1:SCREEN 0:CLS
205 PRINT”Pressione uma tecla de 1 a 4″
210 I$=INPUT$(1)
215 OP=VAL(I$)
220 IF OP4 GOTO 210
225 POKE&HD800,OP
230 COLOR,0,0:SCREEN 7,,,,,3:SET PAGE 1,1:CLS
235 _TURBO ON
240 W=511:H=423:IT=50:OP=PEEK(&HD800)
245 IF OP=1 THEN XL=-2:XH=1:YL=-1:YH=1
250 IF OP=2 THEN XL=-2:XH=-.5:YL=-.5:YH=.5
255 IF OP=3 THEN XL=-1.4:XH=-.9:YL=-.5:YH=-.16
260 IF OP=4 THEN XL=-.4:XH=.1:YL=.8:YH=1.13
265 FOR IX=0 TO W:FOR IY=0 TO H:SET PAGE 1,IY MOD 2
270 X=XL+(XH-XL)*IX/W:Y=YL+(YH-YL)*IY/H
275 CX=X:CY=Y:MI=IT
280 MX=0:MY=0:XX=0:YY=0:XY=0:I=0
285 XY=MX*MY:XX=MX*MX:YY=MY*MY
290 MX=XX-YY+CX:MY=XY+XY+CY
295 I=I+1
300 IF I<MI AND XX+YY<=4 GOTO 285
305 IF I=IT THEN C=0:GOTO 315
310 C=INT(16*LOG(I)/LOG(IT-1))-1
315 PSET(IX,IY2),C
320 NEXT IY:NEXT IX
325 _TURBO OFF
330 NP=2
335 DIM R(NP,15):DIM G(NP,15):DIM B(NP,15)
340 FOR P=0 TO NP:FOR C=0 TO 15
345 READ R(P,C),G(P,C),B(P,C)
350 NEXT C,P
355 FOR P=0 TO NP:FOR C=0 TO 15
360 COLOR=(C,R(P,C),G(P,C),B(P,C))
365 NEXT C:I$=INPUT$(1):NEXT P
370 GOTO 355
375 'FIRE
380 DATA 0,0,0,1,0,0,2,0,0,3,0,0,4,0,0,5,0,0,6,0,0,7,0,0
385 DATA 7,1,0,7,2,0,7,3,0,7,4,0,7,5,0,7,6,0,7,7,0,7,7,7
390 'WIND
395 DATA 0,0,0,0,0,1,0,0,2,0,0,3,0,0,4,0,0,5,0,0,6,0,0,7
400 DATA 0,1,7,0,2,7,0,3,7,0,4,7,0,5,7,0,6,7,0,7,7,7,7,7
405 'EARTH
410 DATA 0,0,0,0,1,0,0,2,0,0,3,0,0,4,0,0,5,0,0,6,0,0,7,0
415 DATA 1,7,0,2,7,0,3,7,0,4,7,0,5,7,0,6,7,0,7,7,0,7,7,7
porque aquele fractal para MSX2 (o segundo) usa 32 tons de cinza e não “50 tons de cinza” ?? desculpem-me pela piadinha infame mas não consegui resistir….rsrsr
E ainda faltam 14 tons de cinza já que o olho humano só enxerga 64 variações desta cor :-). Mas a explicação é simples a SCREEN12 dos MSX2+ codifica as cores num padrão chamado YJK (resumidamente é intensidade luminosa e variações de cores) e que fica armazenado em blocos de 4 pixels assim: Y0+Ja / Y1+Jb / Y2+Ka / Y3 + Kb ; cada ponto tem sua informação de intensidade luminosa armazenada individualmente (5-bit) e compartilham os dados de crominância J (Ja+Jb) e K (Ka+Kb), de 6-bit cada. Como eu jogo a informação de cor fora só me restam os 2^5 tons de cinza, ou seja, 32 pra ficar na tela 😀
Agradeço muito a explicação (aula!)! Pelo que entendi esse formato faz uma certa “compactação” da imagem ao usar menos memória para a informação de cromância do que de luminância de forma similar ao que ocorre na transmissão da televisão colorida analógica. Sendo assim imagino que este modo de tela deva ser similar ao modo “HAM” que era nativo na linha Commodore Amiga e permitIa mostrar telas com milhares de cores simultâneas mas também imagino que assim como ocorria no modo HAM do Amiga, este modo do MSX2+ também deva ser praticamente inviável para atividades que requeram modificação dinâmica e em tempo real da imagem (jogos e manipulação da imagem em tempo real) justamente pelo interdependência de cada pixel com seus vizinhos. É isso mesmo? Abraço!