Neste número: Screen 1 no MSX, Jogo Speed Race e Dicas
Screen 1 no MSX
Artigo Original: Pierluigi Piazzi e Milton Maldonado Jr., Digitação: Wilson Pilon
Mais do que um modo para texto, SCREEN 1 é uma verdadeira tela reconfiguravel, cuja versatilidade será mostrada neste artigo.
O MSX possui vários modos de controlar a tela, incluindo alta resolução gráfica, cores e texto. Um destes modos é o SCREEN 1, considerado por muitos o "primo pobre" das telas, pois em uma primeira análise, não passa de um simples modo texto (32 colunas) que, aparentemente, nada tem de incomum e que ainda perde em desempenho para o modo SCREEN 0 (40 colunas).
No entanto, o SCREEN 1 possui uma série de recursos que podem ser bastante interessantes, como, por exemplo, para jogos de ação.
Mapeamento da Memória
A Organização da tela no modo SCREEN 1 na VRAM (Vídeo RAM) é a seguinte:
- 0000-2047: Tabela de formação de caracteres.
- 6144-6912: Mapa da tela texto.
- 8192-8223: Tabela de cores dos caracteres (ver octetos).
Além destas áreas, existem outras que operam apenas com os Sprites. Estas áreas são as seguintes:
- 6912-7039: Tabela de atributos dos Sprites.
- 14336-16383: Tabela de formação dos Sprites.
A figura abaixo mostra a organização da VRAM do MSX.
Neste artigo, entretanto, trataremos apenas do mapeamento da tela e da redefinição dos caracteres do micro, tanto em relação à forma quanto as suas cores.
Mapeamento da Tela
O mapa da tela no modo SCREEN 1 ocupa 768 bytes (pois 24x32=768). Os primeiros 32 bytes armazenam a primeira linha, os próximos 32 armazenam a segunda e assim por diante, até os últimos 32 bytes, que armazenam a última linha. O início da tela se dá na posição 6144 (decimal) da VRA. É claro que para ler estas posições deve-se usar a função VPEEK e, para alterá-las, o comando VPOKE.
Tabela de Formação dos Caracteres
A tabela de formação dos caracteres inicia na posição 0 da VRAM, ocupando um total de 2048 bytes, indicando ainda a formação dos 256 diferentes caracteres do micro. Um simples cálculo mostra que cada caractere necessita de 8 bytes para ser completamente definido em forma (quem já redefiniu os caracteres do ZX81 ou do ZX Spectrum sabe como funciona).Para quem não sabe, os caracteres são formados por uma matriz de oito linhas por oito colunas, num total de 64 pontos. Cada linha nada mais é que a representação binária de um byte. Por isto, cada caractere necessita de 8 bytes. Deste modo, as posições de 0 a 7 definem o caractere de código 0; de 8 a 15 o caractere de código 1 (não confundir com "1", pois este último tem código 49), e assim por diante.
Ao se chamar o comando SCREEN, o computador transfere automaticamente a tabela original de formação dos caracteres contida na ROM para a tabela na VRAM. Portanto, após redefinir seus caracteres, não utilize este comando pois ele será um tanto quanto destrutivo.
Tabela de Cores dos Caracteres (Octetos)
Internamente, os 256 caracteres do MSX são divididos em 32 grupos de oito caracteres (os octetos). Cada um destes grupos pode ter sua cor de frente e de fundo definida por uma pequena tabela de cores (de apenas 32 bytes) que inicia na posição 8192 e vai até 8223. Naturalmente, os caracteres de 0 a 7 devem ter todos a mesma cor de frente e fundo; idem com os de 8 a 15, até o grupo 248-255.
Para definir a cor de um grupo, deve-se alterar o valor do byte correspondente (exemplo: para alterar o grupo de 0 a 7, o byte será 8192; se for do 8 ao 15, o byte será 8193, etc.).
O valor do byte, obviamente, é que contém a cor de frente e de fundo. Imaginando o byte como uma sequência de 8 bits, teremos nos primeiros quatro bits o código da cor de frente, e nos restantes o código da cor de fundo. Observe que a frente é a cor que um ponto assume quando está aceso, e a de fundo é a que assume quando está apagado. Assim se você deseja que o grupo de 48 a 55 tenha frente vermelha e fundo ciano, comande:
VPOKE 8198,135
O endereço 8198 corresponde à tabela que vai de 48 a 55; o valor 135 é o mesmo que 16 x 8 + 7 (8=vermelho, 7=ciano).
Um modo prático de achar este valor em função das cores de frente e fundo é aplicar a seguinte fórmula:
D=16*Cf+Cb
Onde: Cf é o código da cor de frente; Cb é o código da cor de fundo.
Reciprocamente, podemos determinar os códigos das cores que foram usadas a partir do valor do VPOKE:
Cf=D\16
Cb=D mod 16
Para exemplificar o funcionamento de tudo isto, a listagem mostra uma adaptação do programa TANK ATTACK, extraído do livro "Coleção de Programas para MSX", lançado recentemente pela Aleph Publicações.
Inicialmente, o programa redefine os caracteres alterando os dados da tabela de formação dos mesmos. As formações de cada linha DATA (10-100) contêm nove dados: o primeiro é o código do caractere a ser alterado, e os outros oito indicam como será formada cada uma das oito linhas que compõe o caractere. A sub-rotina responsável pela leitura das instruções DATA está na linha 460. Um loop FOR-NEXT exterior é responsável pela varredura dos códigos dos caracteres e um loop inferior redefine cada um dos caracteres apontados pelo loop exterior. A instrução DATA da linha 110 não entra neste processo; apenas define a matriz de direções de movimentação do tanque.
A sub-rotina das linhas 490 a 510 é uma utilização da propriedade dos octetos como explicado acima: ela modifica as tabelas de cores seguindo a convenção que já foi mostrada.
O jogo é auto explicativo, e as instruções estão localizadas entre as linhas 520 e 590.
Uma técnica interessante para se usar no modo SCREEN 1 é mapear a tela em coordenadas X e Y. Existe uma forma bem conveniente de fazer isto, basta converter o valor de X e Y em um número de memória através do comando DEF FN (linha 140), ou seja, a função calcula o endereço correspondente à posição da tela de coordenadas referenciadas em FNPO.
O cenário de fundo é impresso com o comando PRINT, que usa o caractere de controle (CHR$(1)) para poder imprimir os caracteres de código menor que 32. As partes móveis são colocadas na tela diretamente com auxílio do comando VPOKE, que equivale a imprimir na tela o caractere do código referenciado.
10 DATA 24,10,10,d6,d6,fe,ef,fe,c6
20 DATA 25,fc,fc,70,7f,70,fc,fc,00
30 DATA 26,c6,fe,fe,fe,d6,d6,10,10
40 DATA 27,3f,3f,0e,fe,0e,3f,3f,00
50 DATA 4,18,3c,3d,3e,3d,3c,18,3c
60 DATA 5,18,3c,bc,7c,bc,3c,18,3c
70 DATA 6,00,00,00,18,1b,00,00,00
80 DATA 16,00,3c,56,ff,56,34,18,00
90 DATA 8,00,7f,7f,7f,00,ef,ef,ef
100 DATA 203,3c,7e,7e,7e,7e,7e,7e,7e
110 DATA -32,1,32,-1
120 C$=CHR$(1):SCREEN 1,0,0:COLOR 1,7,7:KEYOFF:DEFINT A-Z:GOSUB 460:GOSUB 490:GOSUB 520:FORI=0TO3:READDS(I):NEXTI
130 CLS:WIDTH 30:PRINTCHR$(219);CHR$(203);STRING$(28,219);:FOR I=1 TO 21:PRINTCHR$(219);:FOR J=1TO28:PRINTC$;CHR$(72);:NEXTJ:PRINTCHR$(219);:NEXT I:PRINTSTRING$(30,219);
140 ON INTERVAL=3 GOSUB 350:DEF FNPO(X,Y)=6144+X+32*Y:VPOKE 6831,16:T=0
150 A=6178:D=2:F=0:P=0:VPOKE A,D*24:STRIG(0)OFF:ON STRIG GOSUB 340:FOR I=1 TO 4:X(I)=15+I:Y(I)=15:NEXT I
160 STRIG(0)OFF:C=STICK(0):IF C=3 THEND=D+1ELSEIFC=7THEND=D-1ELSE180
170 OUT170,154:OUT170,26
180 IF D=-1THEND=3ELSEIFD=4THEND=0
190 VPOKE A,D+24:STRIG(0)ON
200 X=(A-6144)MOD32:Y=(A-6144)\32:FOR I=1 TO 4:Z=8:IF I<4THENZ=32
210 VPOKEFNPO(X(I),Y(I)),Z:Z=4:DX=0:DY=0:IFRND(1)>.5THENDX=SGN(X-X(I))ELSEDY=SGN(Y-Y(I))
220 IF I<4 THEN 260
230 IFVPEEK(FNPO(X(I)+DX,Y(I)))<>32THENIFVPEEK(FNPO(X(I)-DX,Y(I)))=32THENDX=-DXELSEDX=0
240 IFVPEEK(FNPO(X(I),Y(I)+DY))<>32THENIFVPEEK(FNPO(X(I),Y(I)-DY))=32THENDY=-DYELSEDY=0
250 U=FNPO(X(I),Y(I)):IF VPEEK(U+1)+VPEEK(U-1)+VPEEK(U+32)+VPEEK(U-32)=32THENGOSUB410
260 X(I)=X(I)+DX:Y(I)=Y(I)+DY:IFX(I)>XTHENZ=5
270 IFVPEEK(FNPO(X(I),Y(I)))=6THENX(I)=20:Y(I)=15
280 K=VPEEK(FNPO(X(I),Y(I))):IFK>23ANDK<28THEN420ELSEVPOKEFNPO(X(I),Y(I)),Z:NEXT I
290 K=VPEEK(DS(D)+A):IFC<>1THEN330
300 IFK<>8ANDK<>219THEN VPOKE A,32:A=A+DS(D):VPOKE A,D+24:OUT 170,154:OUT 170,26
310 IFK=16THENF=1:FORI=1TO10:BEEP:NEXTI:ELSEIFK=4ORK=5THEN420
320 IFK=203ANDF=1THEN430
330 GOTO 160
340 IF T>0 THEN RETURN ELSE T=A:DT=D:BEEP:INTERVAL ON:RETURN
350 IF T=0 THEN RETURN
360 IF VPEEK(T)=6 THEN VPOKE T,32
370 T=T+DS(DT):IF VPEEK(T)=32 THEN VPOKE T,6:RETURN
380 IF VPEEK(T)=8 THEN VPOKE T,32
390 IFVPEEK(T)=4ORVPEEK(T)=5THENGOSUB470
400 INTERVAL OFF:T=0:RETURN
410 U=FNPO(2,Y(I)):FOR J=U TO U+27:VPOKE J,32:NEXT J:RETURN
420 CLS:LOCATE 0,10:PRINT"VOCE FOI CAPTURADO":GOTO440
430 CLS:LOCATE 0,10:PRINT"VOCE CONSEGUIU"
440 INTERVAL OFF:STRIG(0)OFF:PRINT"Jogar de novo ?";
450 A$=INPUT$(1):IFA$="S"THEN130ELSEIFA$="N"THENENDELSE450
460 CLS:FOR I=0 TO 9:READZ:FOR J=0 TO 7:READ B$:VPOKE J+8*Z,VAL("&H"+B$):NEXT J:NEXT I:RETURN
470 FOR I=1TO4:IFFNPO(X(I),Y(I))<>TTHENNEXTI:RETURN
480 VPOKE T,32:X(I)=20:Y(I)=15:FORJ=1TO5:OUT170,154:OUT170,26:NEXTJ:RETURN
490 VPOKE8192,135:VPOKE8193,97
500 VPOKE8194,246:VPOKE8195,39:VPOKE8217,135:VPOKE8219,176
510 RETURN
520 WIDTH 28:CLS:PRINT" **** TANK ATTACK ****"
530 PRINT:PRINT:PRINT" Voce deve roubar uma pedrapreciosa que fica protegida por quatro androides guardiaoes. A sua unica arma e umtanque de guerra que se movenas quatro direcoes e atirapara abrir caminho entre ossubterraneos."
540 PRINT:PRINT" Tenha muito cuidado com osandroides, pois se qualquerum deles capturar voce, naohavera outra chance..."
550 PRINT:PRINT" Apos roubar a pedra, saiapela passagem (";CHR$(203);") que ficano canto superior da tela. Nao tente sair sem a pedra,pois isto e desastroso e de-saconselhavel..."
560 I$=INPUT$(1)
570 CLS:PRINT" As teclas de cursor servempara controlar o tanque. Useas teclas laterais para vi-rar, a tecla de cima para a-vancar e a barra de espaco para atirar."
580 PRINT:PRINT:PRINTC$;"Y ... Seu tanque":PRINT:PRINTC$;"D ... Androide":PRINT:PRINTC$;"P ... Diamante":PRINT:PRINTCHR$(219);" ... Fronteira":PRINT:PRINTC$;"H ... Parede subterranea":PRINT:PRINTCHR$(203);" ... Saida":PRINT
590 PRINT:PRINT "Aperte uma tecla p/ jogar":I$=INPUT$(1):RETURN
Speed Race
Artigo Original: Marcelo Lima, Digitação: Wilson Pilon
Speed Race é um jogo desenvolvido no micro Expert, podendo rodar em qualquer outro equipamento da linha MSX.
Visando possibilitar a compreensão e facilitar possíveis aprimoramentos, é descrita a seguir, a estrutura do programa:
- Linhas 10 a 110 - Montam as figuras usadas pelo programa.
- Linhas 120 a 190 - Preparam a tela e estabelecem alguns parâmetros.
- Linhas 200 a 240 - Constituem a rotina principal do programa.
- Linha 300 - Atualiza os dados.
- Linhas 310 a 320 - Desenham o nosso carro e o carro do adversário.
- Linhas 330 a 350 - Lêem o estado do joystick.
- Linhas 500 a 530 - Sub-rotina de explosão.
- Linhas 600 a 620 - Atualizarm o recorde e recomeçam o jogo.
- Linhas 700 a 740 - Apresentam o jogo.
- Linha 800 - Sub-rotina de som.
- Linhas 1000 a 1010 - Dados para a construção das figuras.
Para jogar é necessário utilizar um joystick. Pressionando-se o botão 1 do mesmo, a velocidade aumenta, e pressionando-se o 2, ela diminui. Para os que não possuem joystick, e desejam jogar através do teclado, bastará inserir e mudar as seguintes linhas:
214 i$=inkey$
215 if i$="S" or i$="s" then v=v+1
216 if i$="Z" or i$="z" then v=v-1
330 a=stick(0):if a=3 then x=x+8 else if a=7 then x=x-8
Para se obter o caractere da linha 130, pressiona-se as teclas SHIFT, L-GRA e P, simultaneamente.
10 SCREEN1,3,0:KEYOFF:J=3
15 GOSUB800
20 FORI=1TO32:READA
30 S$=S$+CHR$(A)
40 NEXTI:SPRITE$(1)=S$
50 S$=""
90 FORI=1TO32:READA
100 S$=S$+CHR$(A)
110 NEXTI:SPRITE$(0)=S$
120 CLS:GOTO700
130 FORI=0TO22:LOCATE5,I:PRINTCHR$(215):LOCATE18,I:PRINTCHR$(215):NEXTI
140 LOCATE0,4:PRINT"Tempo"
150 LOCATE0,9:PRINT"Vidas"
160 LOCATE0,14:PRINT"Ptos."
170 LOCATE0,19:PRINT"Veloc"
175 LOCATE20,4:PRINT"Record":LOCATE22,6:PRINTUSING"####";RE
180 ONSPRITEGOSUB500
190 V=0:VI=5:P=0:TIME=0:X=134:Z=-20:Y=90:B=120
200 F=INT(RND(-TIME)*10):IFF=5THENL=15ELSEL=22
205 SPRITEON:J=-J
210 FORG=1TOL:Z=Z+3*V:IFZ>190THENZ=-20:P=P+10
214 I$=INKEY$
215 IFI$="A"ORI$="a"THENV=V+1
216 IFI$="Z"ORI$="z"THENV=V-1
217 IFV>15THENV=15ELSEIFV<1THENV=1
218 SOUND1,(15-V):SOUND8,15:T=INT(TIME/60):Y=Y+J
220 IFY<67THENY=67ELSEIFY>134THENY=134
230 GOSUB320:GOSUB330:GOSUB300:NEXT
240 GOTO200
300 LOCATE0,6:PRINTUSING"####";T:LOCATE2,11:PRINTVI:LOCATE0,16:PRINTUSING"####";P:LOCATE2,21:PRINTUSING"##";V:RETURN
310 PUTSPRITE1,(X,B),6:RETURN
320 PUTSPRITE2,(Y,Z),5,1:RETURN
330 A=STICK(0):IFA=3THENX=X+8ELSEIFA=7THENX=X-8
335 IFA=1THENB=100ELSEIFA=5THENB=120
340 IFX>134THENX=134ELSEIFX<67THENX=67
350 GOSUB310:RETURN
500 PUTSPRITE0,(X+3*J,110),15:SOUND0,0:SOUND1,0:SOUND6,31:SOUND7,1:SOUND8,16:SOUND11,100:SOUND12,100:SOUND13,9
505 SPRITEOFF
510 FORO=1TO2000:NEXTO:PUTSPRITE0,(0,0),0:PUTSPRITE2,(255,0),0,1
520 VI=VI-1:IFVI=-1THENGOTO600
530 V=0:X=134:Z=-20:GOSUB800:RETURN200
600 PUTSPRITE1,(X,B),0
610 IFP>RETHENRE=P
620 GOTO 120
700 OPEN"grp:"FOROUTPUTAS#1
710 SCREEN3
711 PSET(30,30):PRINT#1,"SPEED"
712 PSET(90,80)
715 PRINT#1,"RACE"
720 CLOSE
730 FORI=1TO3000:NEXTI
740 SCREEN1:CLS:GOSUB800:GOTO130
800 SOUND0,255:SOUND1,15:SOUND6,31:SOUND7,8:SOUND8,0:SOUND11,0:SOUND12,0:SOUND13,0:RETURN
1000 DATA14,223,255,255,223,31,17,17,17,223,255,255,223,14,0,0,0,96,224,224,96,0,0,0,0,96,224,224,96,0,0,0
1010 DATA4,31,95,15,31,63,63,159,63,63,31,30,76,0,8,0,0,68,224,226,248,252,252,248,240,250,240,192,5,2,80,0
Dicas
Efeitos com Circle
Artigo Original: Ricardo Hunsche, Digitação: Wilson Pilon
Veja os efeitos produzidos com o Circle nesse curioso desenho gráfico.
5 REM RICARDO HUNSCHE
10 SCREEN2:F=1:COLOR13,1
20 FOR X=1TO90
30 CIRCLE(120,100),F
40 F=F+1:NEXTX
50 GOTO50
Pokeando
Artigo Original: Jorge Pablo Zapata Rivera, Digitação: Wilson Pilon
Para quem possui um compatível com o MSX, aqui vão alguns POKEs que irão ajudá-lo no confeccionamento dos seus programas.
- POKE 62384,N : Faz o tabulamento horizontal semelhante ao WIDTH (mínimo de 1 e máximo de 40).
- POKE 62385,N : Faz o tabulamento vertical (mínimo de 1 e máximo de 24).
- POKE 62428,N : Coloca o cursor na linha N (mínimo de 0 e máximo de 23).
- POKE 62429,N : Coloca o cursor na coluna N (mínimo de 0 e máximo de 39)
- POKE 64681,N : Se N for qualquer valor, exceto 0, o cursor irá aparecer após uma impressão.
- POKE 64683,N : Se N for qualquer valor, exceto 0, só poderão ser impressas letras maiúsculoas.
- POKE 64687, 255 : Executa um CLS. Se estiver em uma linha de programação, o CLS será executado após o STOP.
Para finalizar, use a rotina abaixo para reinicializar o sistema:
DEFUSR=0 : A = USR(0)
Desabilitando o BREAK
Artigo Original: Sérgio Augusto Freire de Souza, Digitação: Wilson Pilon
Para desabilitar o uso do BREAK (CTRL+STOP) em um programa o exemplo da listagem.
A linha 10 habilita o uso do comando ON STOP GOSUB. Na linha 20 há um LOOP que terminará ao ser acionado BREAK, operando a mensagem da linha 100, e na linha 110 há uma pausa antes do retorno à linha 30. O END da linha 40 é só para a rotina não entrar em LOOP novamente, ao usar esta rotina em seu programa utilize apenas os comandos das linhas 10 e 20, sendo que na linha 20 o GOTO 20 pode ser dispensado.
10 STOP ON
20 ON STOP GOSUB 100:GOTO20
30 PRINT" MICRO SISTEMAS "
40 END
100 CLS:PRINT"Uma tentativa de BREAK foi feita."
110 FOR I=1 TO 2000:NEXT I
120 RETURN 30
WebMSX
- ms-56.dsk: Rode os programas pelo WebMSX