Você está na página 1de 38

Desenvolvimento de jogos/Programao Megadrive

Desenvolvimento de jogos/Programao Megadrive


Introduo
Este wikibook destina-se queles que estejam interessados no desenvolvimento de jogos para o videogame conhecido como Mega Drive. (Em construo)

Ferramentas
Montadores
Tambm conhecidos pelo termo ingls assemblers, geram o cdigo de mquina referente ao cdigo fonte escrito na linguagem de montagem (assembly). No caso do Mega Drive, o cdigo escrito para os processadores Motorola 68000 (tambm conhecido como M68k ou M68000) e Z80, da Zilog, sendo o Z80 um coprocessador de udio e para "compatibilidade" com jogos de Master System. GAS O GNU Assembler (GAS) [1]. Ele bem completo, pleno de recursos e genrico quanto a processador. Sua sintaxe segue o padro AT&T em vez do da Intel. Caso seja necessrio compilar o GAS para o M68k, utilize os seguintes comandos: ./configure -target=m68k-coff make O primeiro comando configura o alvo de montagem ser o processador famlia M68k, sem sistema operacional. O segundo efetivamente compila os programas componentes do GAS, que so: addr2line ar as cxxfilt ld nm objcopy objdump ranlib readelf size strings strip

Os mais usados, para fins de programas para Mega Drive, so o as (o montador/assembler), o ld (o ligador/linker) e o objcopy (para gerar o arquivo no formato binrio correto).

Desenvolvimento de jogos/Programao Megadrive Usando o as as -m68000 -o arquivo.o arquivo.s importante o uso do parmetro -m68000, porque o padro 68020. O parmetro -o serve para definir o nome do arquivo objeto de sada (o padro "a.out"). Por fim, o no opcional: o cdigo-fonte. Usando o ld Aps feita as compilaes de todas os cdigos do programa, preciso lig-los. ld --oformat=binary -Ttext=0 -o rom.bin arquivo.o [outros .o] --oformat=binary e -Ttext=0 so necessrios para o correto formato do arquivo binrio. -o, como j mencionado para o as, define o nome do arquivo binrio de sada, no caso "rom.bin" O parmetro obrigatrio para o ld , obviamente, o(s) arquivo(s) objeto(s) que compe o programa.

Compiladores
BasiEgaXorz Compilador de BASIC para Mega Drive, muito fcil de usar, e vem com muitos exemplos. Pode ser baixado neste site [2] SGCC - Sega Genesis C Compiler Compilador de C para Mega Drive. Embora tenha alguns problemas, como o fato de usar um dialeto arcaico da linguagem C, (Sintaxe K&R, para ser mais exato), ele extremamente simples de usar, bastando descompactar e usar, alm de j vir com alguns exemplos simples. Pode ser baixado deste site [3], ou deste [4] GCC68k - GNU C Compiler for 68k Verso do GNU C adaptado para o processador MC68000. Suporta tanto C como C++, podendo tambm suportar outras linguagens, como Fortran, Pascal e outros, dependendo da configurao. Tem a desvantagem de ser ligeiramente mais difcil de usar do que o SGCC. Neste site [5], voc pode baixar uma verso deste compilador j preparada para o Mega Drive.

Bsico
Para os exemplos desta seo, ser utilizado o BasiEgaXorz, por ser mais simples de usar.

Desenvolvimento de jogos/Programao Megadrive

Escrevendo texto na tela


Usando o BasiEgaXorz, esta tarefa se torna bastante simples: print "Ola, mundo!!!"

Definindo a palheta de cores


O Megadrive possui quatro palhetas de cores, cada uma com 16 cores, selecionveis dentre 512. O BasiEgaXorz possui dois comandos para setar as palhetas do Megadrive: PALLETTE seta uma nica cor de uma nica palheta. A sua sintaxe : Pallette <cdigo RGB>, <n da palheta>, <n da cor> <cdigo RGB> um nmero hexadecimal que repesenta os tons de vermelho, verde e azul que compem a cor desejada. Para calcular o cdigo equivalente cor, utilize a frmula (R*2)+(G*32)+(B*512), onde: R representa o tom de vermelho, entre 0 e 7 G representa o tom de verde, entre 0 e 7 B representa o tom de azul, entre 0 e 7 <n da palheta> indica o nmero da palheta que se deseja modificar <n da cor> indica qual das cores desta palheta ser alterada Exemplo: ink 0 print "Texto usando a palheta0" ink 1 print "Texto usando a palheta1" ink 2 print "Texto usando a palheta2" ink 3 print "Texto usando a palheta3" ' ink 0 print print "Pressione qualquer botao..." while joypad()=0: wend waitpadup 0 ' pallette 14, 0, 1 pallette 224, 1, 1 pallette 3584, 2, 1 pallette 238, 3, 1 ' ink 1 print "Observe como a cor do texto mudou ao" print "alterar a palheta" O exemplo acima imprime uma linha de texto com cada palheta, espera o usurio pressionar qualquer boto do joystick, e ento altera a cor 1 de cada palheta, a qual corresponde cor utilizada pelo texto; como consequncia, o texto muda de cor.

Desenvolvimento de jogos/Programao Megadrive PALLETTES pode setar vrias cores de uma determinada palheta de uma s vez. A sua sintaxe :
Pallettes <rtulo dos dados>, <n da palheta>, <cor inicial>, <n de cores>, [Deslocamento]

<rtulo dos dados> indica qual rtulo de dados ser lido para definir as cores da palheta indicada (veja o exemplo abaixo para entender melhor) <n da palheta> nmero da palheta que ser alterada <cor inicial> cor inicial a ser alterada. Por exemplo, se a cor inicial for 4 e o nmero de cores for 3, sero alteradas as cores 4, 5 e 6 <n de cores> o nmero de cores que sero alteradas [Deslocamento] parmetro opcional que indica a posio dentro dos dados indicados pelo rtulo a partir da qual os dados sero lidos. Exemplo: ink 0 print "Texto usando a palheta0" ink 1 print "Texto usando a palheta1" ink 2 print "Texto usando a palheta2" ink 3 print "Texto usando a palheta3" ' ink 0 print print "Pressione qualquer botao..." while joypad()=0: wend waitpadup 0 ' pallettes pallette1, 0, 0, 16 pallettes pallette2, 1, 0, 16 pallettes pallette3, 2, 0, 16 pallettes pallette4, 3, 0, 16 ' ink 1 print "Observe como a cor do texto mudou ao" print "alterar a palheta, assim como a cor" print "do fundo." ' pallette1: DATAINT $0ECA,$00EE,$0EA8,$0CA6,$0CAC,$08CA,$08AA,$0A68 DATAINT $0866,$0ACE,$0442,$0686,$066A,$0AAE,$06AA,$0000 pallette2: DATAINT $0002,$00AA,$002A,$004A,$006E,$02AE,$002C,$04AE DATAINT $02EE,$04EE,$0046,$0468,$04AA,$028A,$08CC,$0000 pallette3: DATAINT $0620,$0088,$0A62,$0CEC,$0644,$0CA4,$0684,$06A8 DATAINT $0868,$0424,$0444,$0222,$0648,$0428,$0000,$0000 pallette4: DATAINT $0422,$0044,$0426,$0446,$086A,$0CEE,$044A,$0866 DATAINT $06AE,$0642,$0202,$0244,$0662,$0000,$0000,$0000

Desenvolvimento de jogos/Programao Megadrive No exemplo acima, pallette1, palette2, palette3 e palette4 so rtulos que apontam para dados, os quais, neste caso, so definidos pelo comando DATAINT. O cifro na frente de cada nmero serve para indicar que o nmero em questo est em notao hexadecimal. Isso torna mais fcil visualizar a cor que est sendo definida, visto que os trs ltimos dgitos do cdigo da cor em hexa correspondem justamente aos valores de azul, verde e vermelho, respectivamente. Observe, tambm, que a cor do fundo tambm foi alterada, porque a cor zero da palheta zero tambm mudou. Importante: Se for copiar e colar este exemplo para o BasiEgaXorz, lembre-se de tirar o espao esquerda dos rtulos, mas apenas dos rtulos. Isto necessrio, porque o BasiEgaXorz pressupe que qualquer linha que comece com um ou mais espaos esquerda no contenha um rtulo.

Lendo o joystick
Existem algumas funes para o BasiEgaXorz que fazem o software interagir com o joystick, vou lista-las primeiramente, e a seguir dou um exemplo mais prtico. WaitPadUp <# do controle> Espera que o device do numero especificado seja ligado ao console. Voc pode fazer o jogo pausar se o controle for removido, ou caso o jogador selecione a opo de 2 players, verificar a existencia de um segundo controle para prosseguir. Importante: os valores para o primeiro e o segundo controle so 0 e 1 respectivamente. Joypad(<# do controle>) Essa funo de longe a mais importante para interao com o controle. Essa funo retorna o bit do evento correspondente. A tabela a baixo mostra a relao de Bit-Evento. Bit 0 1 2 3 4 5 6 7 8 9 10 11 Hex &h001 &h002 &h004 &h008 &h010 &h020 &h040 &h080 &h100 &h200 &h400 &h800 Decimal 1 2 4 8 16 32 64 128 256 512 1024 2048 Evento Cima Baixo Esquerda Direita B C A Start Z (6-Botes) Y (6-Botes) X (6-Botes) Mode (6-Botes)

No vou entrar muito em detalhes, vocs podem procurar no site da BasiEgaXorz por uma documentao mais detalhada, mas quando se utiliza joystick de 3 botoes os bits referentes aos botes ZYX no estaro 'limpos', e sim tera um valor randomico qualquer, I.E, lixo. Tomar cuidado com isso. Vamos ao exemplo:

Desenvolvimento de jogos/Programao Megadrive

Cole o exemplo abaixo no BasiEgaXorz, lembrando que deve haver um espao em branco antes de cada comando. Reparem que foi utilizado joypad() sem nenhum parmetro, caso este esteja omitido o padro o primeiro controle.
WaitPadUp 'se omitir o valor 0 ou 1, ser o valor padrao 0 Print "Controle 1 esta conectado"

' Player Joypad Inputs while 1 sleep 6 joy = joypad() if joy.0 then Print "cima" endif if joy.1 then Print "baixo" endif if joy.2 then Print "esquerda" endif if joy.3 then Print "direita" endif if joy.4 then Print "b" endif if joy.5 then Print "c" endif if joy.6 then Print "a" endif if joy.7 then Print "start" endif if joy.8 then Print "z" endif if joy.9 then Print "y" endif if joy.10 then Print "x" endif if joy.11 then 'mode 6 button ' x ' y ' z ' start ' a ' c ' b ' direita ' esquerda ' baixo ' cima 'so para nao ficar num loop frenetico e ocupar muito a cpu 'mesma coisa que no waitpadup

Print "mode 6 button" endif 'voce tambem pode usar capturar mais de um envento ao mesmo tempo, por exemplo.

Desenvolvimento de jogos/Programao Megadrive


'perceba que ele caira em todos os if's no do botao B, no do botao C, e no BC. 'se quizer aninhar os ifs - else, pode facilmente impedir isso. 'Nao fiz pois achei que ficaria mais claro os exemplos assim. if joy.4 and joy.5 then print "bc" endif wend

O ideal utilizar select-case, ao invs de estrutura if-else por questes de desempenho, alm de produzir uma melhor legibilidade ao cdigo. No caso do select utilize os valores decimais da tabela. Caso queiram capturar dois botoes por exemplo, some os valores. Um exemplo com as 4 diagonais. WHILE 1 SLEEP 6 JOY = JOYPAD() SELECT CASE JOY CASE 1: PRINT "CIMA" EXIT CASE CASE 2: PRINT "BAIXO" EXIT CASE CASE 4: PRINT "ESQUERDA" EXIT CASE CASE 5: PRINT "DIAGONAL ESQUERDA PRA CIMA" EXIT CASE CASE 6: PRINT "DIAGONAL ESQUERDA PRA BAIXO" EXIT CASE CASE 8: PRINT "DIREITA" EXIT CASE CASE 9: PRINT "DIAGONAL DIREITA PRA CIMA" EXIT CASE CASE 10: PRINT "DIAGONAL DIREITA PRA BAIXO" EXIT CASE CASE ELSE: EXIT SELECT END SELECT WEND

Desenvolvimento de jogos/Programao Megadrive

Movendo objetos pela tela


Utilizando o loop do exemplo acima que l os comandos do controle. As unicas adies des comandos foram o addsprite, propsprite, movesprite, e loadtiles. Irei comentar no codigo mesmo a funo de cada coisa, caso alguem queria criar um tpico explicando cada comando, fique a vontade. Explicando superficialmente sprites so aquelas sequencias de imagens ([6]) que permite fazer a ilusao de um personagem em movimento. possivel, e comumente utilizado mas no exemplo ficou faltando, de trocar as imagens do sprite dado o movimento. LOADTILES TILES,1,256 'CARREGA A 'IMAGEM' DO LABEL TILES QUE SER O NOSSO CURSOR, UMA IMAGEM 8X8 PIXIELS. 'OS PARAMETROS, 1 E 256 SO RESPECTIVAMENTE A QUANTIDADE DE TILE (CADA TILE UM 'BLOCO' DE 8X8 PIXIELS) E 'O ENDEREO DE MEMORIA EM QUE O TILE SER ALOCADO PALLETTES PALLETTEDATA,0,0,15 'MODIFICA A PALETA DE CORES NUMERO ZERO COM AS CORES DO LABEL PALLETTEDATA, QUE CONTEM AS CORES DO NOSSO CURSOR 'ESSE COMANDO J FOI EXPLICADO ACIMA SPRITE=ADDSPRITE(1,1) 'CRIA UM SPRITE DE 1 TILE DE ALTURA E 1 TILE DE COMPRIMENTO (8X8 PIXIELS), E RETONA O ENDEREO DO SPRITE PROPSPRITE SPRITE,256,0 DESENHA O TILE' DE ENDEREO SPRITE, INICIANDO NO ENDEREO DE MEMORIA 256, UTILIZANDO A PALETA DE CORES NUMERO 0 X=280 Y=235 WHILE 1 SLEEP 2 MOVESPRITE SPRITE,X,Y COORDENADAS X,Y JOY = JOYPAD() SELECT CASE JOY CASE 1: Y-EXIT CASE CASE 2: Y++ EXIT CASE CASE 4: X-EXIT CASE CASE 5: X--

'MOVIMENTA O SPRITE PARA AS

Desenvolvimento de jogos/Programao Megadrive Y-EXIT CASE 6: X-Y++ EXIT CASE 8: X++ EXIT CASE 9: X++ Y-EXIT CASE 10: X++ Y++ EXIT CASE CASE ELSE: EXIT END SELECT WEND TILES: 'TILE CONVERTIDO, EU UTILIZEI UMA FERRAMENTA PARA FAZER ESSA CONVERSAO 'E EMBORA CHATO NO IMPOSSIVEL DE SE FAZER NA MAO NAO ' UMA ESPCIE DE MAPA 8X8 PIXIELS, ONDE OS NUMEROS REPRESENTA OS NUMEROS DA PALETA DE CORES '1 = PRETO, 2 = VERMELHOR MAIS CLARO, 3 = VERMELHO MAIS ESCURO, 4 = UM VERMELHO 'INTERMEDIARIO' 'SE REPARAREM BEM CONSEGUIRAO VER A NAVE DESENHADA NESSE 'MAPA' AO LADO 'ALTEREM ESSE MAPINHA E AS CORES DA PALETA VCS ENTENDERAO COMO FUNCIONA. DATALONG $11122111 ' Tile #0 DATALONG $11322311 DATALONG $11322311 DATALONG $13244211 DATALONG $13244231 DATALONG $32433423 DATALONG $32433423 DATALONG $22222222 PALLETTEDATA: 'PALLET COM AS CORES DO TILE, EU UTILIZEI UMA FERRAMENTA PARA DETECTAR AS CORES. 'MAS POSSIVEL, E NEM TO DIFICIL, FAZER A PALETA DE CORES "NA MAO".

CASE

CASE

CASE

CASE

SELECT

Desenvolvimento de jogos/Programao Megadrive DATAINT DATAINT $0000,$0000,$000E,$0004,$0008,$0000,$0000,$0000 $0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000

10

Exibindo uma imagem no fundo da tela


Sei que a explicao no est muito didtica mas estou tentando postar aqui conforme tenho tempo. Pela falta de documentao e exemplo em portugues, vamos a mais um exemplo pratico. Vou usar praticamente tudo do exemplo anterior, espero que tenha ficado claro. Um pouco de teoria antes do exemplo. No mega drive existe 3 planos SCROLL_A, SCROLL_B, E WINDOW. O plano SCROLL_B, possui a menor prioridade de todas, seguido pelo SCROLL_A, e por final WINDOW. Manipulando esses 3 planos que damos a noo de 'profundidade' ao jogo, um elemento mais 'proximo', I.E, em um plano de maior prioridade, ir tapar o outro criando essa ilusao. O mais importante os spirtes terao uma prioridade mais alta, por isso nem me dei ao trabalho de atribuir os planos no exemplo a seguir. Existem mais comandos do que os que vou listar a baixo, recomendo ir buscar a documentao do BasiEgaXorz, vou explicar o basico s. Voc pode usar os comandos: SETTEXTPLANE <SCROLL_A/SCROLL_B/WINDOW> Esse comando torna padro para o ASCII, comandos tipo print e etc. SETGFXPLANE <SCROLL_A/SCROLL_B/WINDOW> Esse comando permite escolher qual ser o plano padro dos comandos de desenho, drawtile, drawtiles. SETSCROLLPLANE <SCROLL_A/SCROLL_B> Escolhe qual plano ser 'rolado'. Esse no um topico sobre scroll, estou explicando por que utilizei no codigo fonte e creio que ficar mais claro agora. Para adicionar as as imagens ao 'fundo', isto imagens de um determinado plano. Existe varios comandos comando drawtile, drawtiles, drawtilesovr, drawtilesinc, DrawTilesOvr, drawtilesinc2. Por hora eu no vou entrar em detalhes nesses varios comandos, vou explicar somente o drawtile (depois eu edito o topico com o resto dos comandos). DRAWTILE <POSICAO DA MEMORIA>, <X DA TELA>, <Y DA TELA> Desenha o determinado tile na tela, na posico x,y. Com um for voc pode preencher toda tela com a mesma imagem, ou armazenar varios tiles que montem uma imagem maior e monta-la tambm com um for, sem maiores grandes problemas. Dito isso, vamos ao exemplo prtico. Boa parte do cdigo foi retirado do exemplo acima ento no tero dificuldade de entender a maioria das coisas, se entenderam o anterior. LOADTILES TILES,4,256 'CARREGA A 'IMAGEM' DO LABEL TILES QUE SER O NOSSO CURSOR, UMA IMAGEM 8X8 PIXIELS. 'OS PARAMETROS, 4 E 256 SO RESPECTIVAMENTE A QUANTIDADE DE TILE (CADA TILE UM 'BLOCO' DE 8X8 PIXIELS) E 'O ENDEREO DE MEMORIA EM QUE O TILE SER ALOCADO 'REPAREM QUE ALTEREI A FUNCAO LOADTILES AGORA PARA CARREGAR 4 TILES A PARTIR DE 256

Desenvolvimento de jogos/Programao Megadrive PALLETTES PALLETTEDATA,0,0,15 'MODIFICA A PALETA DE CORES NUMERO ZERO COM AS CORES DO LABEL PALLETTEDATA, QUE CONTEM AS CORES DO NOSSO CURSOR 'ESSE COMANDO J FOI EXPLICADO ACIMA SPRITE=ADDSPRITE(1,1) 'CRIA UM SPRITE DE 1 TILE DE ALTURA E 1 TILE DE COMPRIMENTO (8X8 PIXIELS), E RETONA O ENDEREO DO SPRITE PROPSPRITE SPRITE,256,0 DESENHA O TILE' DE ENDEREO SPRITE, INICIANDO NO ENDEREO DE MEMORIA 256, UTILIZANDO A PALETA DE CORES NUMERO 0 X=280 Y=235 SETTEXTPLANE SCROLL_A SETGFXPLANE SCROLL_B SETSCROLLPLANE SCROLL_B 'GERA AS ESTRELAS NO FUNDO, ESCOLHE ENTRE 3 TIPOS DE ESTRELAS, A GRANDE, A PEQUENA CLARA, E A PEQUENA ESCURA RANDOMIZE 2 'E ALOCA 100 DELAS 'RANDOMICAMENTE' PELA TELA. COMO ESTOU UTILIZANDO A MESMA SEMENTE, SEMPRE SER NOS MESMOS LUGARES FOR I=0 TO 200 'IMPORTANTE: ISSO O TIPO DE COISA QUE NO SE DEVE FAZER, A FUNO RANDOM GERA UM PROCESSAMENTO DESNECESSRIO. DRAWTILE 257+RND(3),RND(40)+1,RND(63)+1 'E O PROCESSADOR DO MEGA DRIVE NO TEM TANTO PODER COMPUTACIONAL PARA FICAR DESPERDICANDO. NEXT ' MUITO MELHOR ESCOLHER AS POSICOES E USAR O DRAWTILE: 'DRAWTILE <POSICAO DA MEMORIA>, COORDENADA X, COORDENADA Y 'VOU DECLARAR UMAS CONSTANTES PARA DEIXAR O CODIGO MAIS LEGIVEL CONST #MAX_X=438 'NADA HAVER COM O ASSUNTO EM QUESTAO, MAS DECLAREI ESSAS CONTANTES PARA LIMITAR A NAVE DE SAIR DA TELA CONST #MAX_Y=343 CONST #MIN_X=130 CONST #MIN_Y=148 INK 1 WHILE 1 I++ 'ISSO DEVE DAR ALGUM ERRO, QUASE CERTEZA... UMA HORA A VARIAVEL I IRA ULTRAPASSAR O VALOR MAXIMO DO INTEGER, EU NAO VOU FICAR TRATANTO

11

Desenvolvimento de jogos/Programao Megadrive 'ESSAS EXEES NO EXEMPLO. MAS NINGUEM DEVE TER DIFICULDADE COM ISSO. SCROLL2 DOWN, I SCROLL_B, PARA A POSICAO I... 'MOVE O PLANO DE SCROLL,

12

SLEEP 1 'OBSERVAO SOBRE O SLEEP, CADA 1 DE SLEEP EQUIVALE A 1HZ DA TV OU SEJA 1/60s SLEEP 60 IGUAL A 1 SEGUNDO LOCATE 0,0 'MOVE O CURSOS DE TEXTO PARA A POSICAO 0,0 PRINT "COORD: ";X;" - ";Y; 'IMPRIMI A COORDENADA DO CURSOR... A CADA LOOP O VALOR SERA ATUALIZADO NA TELA JOY = JOYPAD() SELECT CASE JOY CASE 1: IF Y > #MIN_Y THEN Y-ENDIF EXIT CASE 'AQUI ANTES DE MOVER A NAVE PARA QUALQUER DIREO EU FIZ UM VERIFICACAO SE ELA PODE AINDA MOVER CASE 2: 'DE RESTO A MESMA INTERACAO COM O CONTROLE DE ANTES. IF Y < #MAX_Y THEN Y++ ENDIF EXIT CASE CASE 4: IF X > #MIN_X THEN X-ENDIF EXIT CASE CASE 5: IF X > #MIN_X AND Y > #MIN_Y THEN X-Y-ENDIF EXIT CASE CASE 6: IF X > #MIN_X AND Y < #MAX_Y THEN X-Y++ ENDIF EXIT CASE

Desenvolvimento de jogos/Programao Megadrive CASE 8: IF X < #MAX_X THEN X++ ENDIF EXIT CASE CASE 9: IF X < #MAX_X AND Y > #MIN_Y THEN X++ Y-ENDIF EXIT CASE CASE 10: IF X < #MAX_X AND Y < #MAX_Y THEN X++ Y++ ENDIF EXIT CASE CASE ELSE: EXIT SELECT END SELECT MOVESPRITE SPRITE,X,Y 'MOVIMENTA O SPRITE PARA AS COORDENADAS X,Y WEND TILES: 'TILE CONVERTIDO, EU UTILIZEI UMA FERRAMENTA PARA FAZER ESSA CONVERSAO 'E EMBORA CHATO NO IMPOSSIVEL DE SE FAZER NA MAO NAO ' UMA ESPCIE DE MAPA 8X8 PIXIELS, ONDE OS NUMEROS REPRESENTA OS NUMEROS DA PALETA DE CORES '1 = PRETO, 2 = VERMELHOR MAIS CLARO, 3 = VERMELHO MAIS ESCURO, 4 = UM VERMELHO 'INTERMEDIARIO' 'SE REPARAREM BEM CONSEGUIRAO VER A NAVE DESENHADA NESSE 'MAPA' AO LADO 'ALTEREM ESSE MAPINHA E AS CORES DA PALETA VCS ENTENDERAO COMO FUNCIONA. 'EDIT: FICOU FEIO MAS EU FIZ AS ESTRELAS MANUALMENTE DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG $11122111 $11322311 $11322311 $13244211 $13244231 $32433423 $32433423 $22222222 'NAVE, POSICAO 256

13

Desenvolvimento de jogos/Programao Megadrive DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG $11111111 $11111111 $11111111 $11116111 $11165611 $11116111 $11111111 $11111111 $11111111 $11111111 $11511111 $11111111 $11111111 $11111111 $11111111 $11111111 $11111111 $11111111 $11111111 $11111111 $11111161 $11111111 $11111111 $11111111 'ESTRELA GRANDE, POSICAO 257

14

'ESTRELA PEQUENA CLARA, POSICAO 258

'ESTRELA PEQUENA ESCURA, POSICAO 259

PALLETTEDATA: 'PALLET COM AS CORES DO TILE, EU UTILIZEI UMA FERRAMENTA PARA DETECTAR AS CORES. 'MAS POSSIVEL, E NEM TO DIFICIL, FAZER A PALETA DE CORES "NA MAO". 'INSERI AS CORES 5 E 6 MANUALMENTE PARA FAZER AS ESTRELAS (DOIS TONS DE CINZA) 'PODERIA FAZE-LAS VERMELHAS TB APROVEITANDO AS CORES QUE A NAVE ESTA UTILIZANDO. DATAINT $0000,$0000,$000E,$0004,$0008,$0CCC,$0444,$0000 DATAINT $0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000 OBS: Qualquer editor, revisor, fique a vontade para modificar ou deixar mais claro o conteudo.

Seu primeiro jogo: Como fazer um clone do "Pong"


Pong sem dvida um grande exemplo de jogo, devido sua simplicidade um timo exerccio para quem est comeando a programar. A ttulo de informao foi o primeiro video game lucrativo da historia. Se no sabe do que se trata, esperto que essa imagem possa esclarecer. [7] Para comear vamos montar a estrutura do arquivo em BEX e ir progressivamente completando a cada tpico. Para comear a explicao gostaria de falar que os voc deve escolher uma posio de memoria em que os tiles sero armazenados. Contudo, da posio 0 at 255, j esto preenchidos com a tabela ascii [8]. Eu irei fazer uso desses caracteres para desenhar a tela com o comando drawtile e passando o endereo deles ao comando.

Desenvolvimento de jogos/Programao Megadrive Nosso ponto de "partida" ser o exemplo abaixo, importante que entenda o que est acontecendo no cdigo para prosseguir. Por isso est com muitos comentrios. Alm disso h vrias substituies que podem ser feitas para deixar o cdigo mais otimizado, mas acredito que prejudicaria o entendimento, por isso vai assim mesmo. Quando esse exemplo foi feito, o BasiEgaXorz no dava suporte nmero negativo, as ltimas verses j o fazem.
'IGNORA AS OPES DE COMPILAO DA GUI, E COMPILA O JOGO PARA MEGA DRIVE (CARTUCHO) OPTION CARTRIDGE 'OBRIGA EXPLICITAMENTE A DECLARAO DE VARIVEIS (BOAS PRTICA) OPTION EXPLICIT 'DESABILITA A SENSIBILIDADE A CAIXA ALTA PARA VARIAVEIS, LABELS, FUNCES, ETC. OPTION CASESENSE 'TTULO QUE SER EXIBIDO NA JANELA DO SEU EMULADOR. (DEPOIS TITULO INSERIDO AUTOMATICAMENTE PELO BASIEGAXORZ) OPTION TITLE, "PONG!"

15

'ATRIBUI OS COMANDOS DE DRAW PARA O PLANO SCROLL_B POR PADRO, E OS DE TEXTO AO PLANO SCROLL_A SETGFXPLANE SCROLL_B SETTEXTPLANE SCROLL_B

'EXECUTA A SUB QUE APRESENTAR A TELA DE APRESENTAO DO JOGO APRESENTACAO SLEEP 10 'EXECUTA A SUB QUE IR DESENHAR A TELA DO PONG DESENHA_TELA

'ALTERA O PADRO TO TEXTO PARA O SCROLL_A

SETTEXTPLANE SCROLL_A 'ADICIONAR OS SPRITES DOS JOGADORES E A BOLA DIM JOGADOR AS INTEGER DIM CPU AS INTEGER DIM BOLA AS INTEGER

JOGADOR=ADDSPRITE(4,1) CPU=ADDSPRITE(4,1) BOLA=ADDSPRITE(1,1)

'ALOCA OS SPRITES DOS JOGADORES LOADTILES TILEDATA, 4, 256

'INSERE DUAS CORES NA PALETA DE COR (DOIS TONS DE CINZA) PALLETTE 2184, 0, 2 PALLETTE 3276, 0, 3

'ATRIBUI EM QUAL REGIO DA MEMRIA O INICIO DO SPRITE PROPSPRITE JOGADOR,256, 0 PROPSPRITE CPU,256, 0 PROPSPRITE BOLA,7,2

Desenvolvimento de jogos/Programao Megadrive


'POSICIONA OS SPRITES NA TELA MOVESPRITE JOGADOR, 136, 218 MOVESPRITE CPU, 432,218 MOVESPRITE BOLA, 142, 229

16

'LOOP DO JOGO 'VOU REMOVER TUDO DO LOOP WHILE 1 SLEEP 1 MOVE_SPRITE JOGADOR WEND

'FUNO QUE DESENHA A TELA (REDE, LATERAIS, JOGADORES) DECLARE SUB DESENHA_TELA() 'DECLARA A VARIVEL DENTRO DA FUNO COMO LOCAL, A MEMRIA SER LIBERADA APS O TERMINO DA FUNO (BOA PRTICA) LOCAL I AS INTEGER 'ITERA UMA VEZ PARA CADA COLUNA FOR I=1 TO 38 'AS POSIES DE MEMRIA ANTES DE 256 SO RESERVADAS PARA OS CARATERES. 'IMPRIME A LINHA SUPERIOR DRAWTILE 205,I,1 'IMPRIME A LINHA INFERIOR DRAWTILE 205,I,26 NEXT FOR I=2 TO 25 'IMPRIME A LINHA VERTICAL DRAWTILE 186, 19, I NEXT 'MOVE O CURSOR DE TEXTO PARA A POSIO 0,1 (O COMANDO LOCATE USA AS COORDENADAS Y,X E NO X,Y) LOCATE 1,0 'MUDA A COR PARA VERDE INK 2 PRINT "JOGADOR" LOCATE 1,35 PRINT "CPU" 'VOLTA A COR ORIGINAL INK 0 END SUB

'FUNO QUE IMPRIME A TELA INICIADO DO JOGO E PRESSIONAR START PARA SEGUIR EM FRENTE DECLARE SUB APRESENTACAO() LOCATE 10,10 'MUDA A COR DO TEXTO PARA VERDE INK 2 PRINT "PONG - PRESS START" 'VOLTA A COR ORIGINAL INK 0

Desenvolvimento de jogos/Programao Megadrive


'EXECUTA UMA ESPERA AT QUE O BOTO DE START SEJA PRESSIONADO. (USE O COMANDO SLEEP (BOA PRTICA)) WHILE JOYPAD() != 128 : SLEEP 2 : WEND CLS END SUB

17

'TESTA E MOVE O SPRITE DO JOGADOR, SE O MOVIMENTO FOR PERMITIDO DECLARE SUB MOVE_SPRITE(JOGADOR AS INTEGER) LOCAL JOY AS INTEGER JOY = JOYPAD() 'PARA CIMA IF JOY.0 THEN IF SPRITEPOSY(JOGADOR) > 142 THEN SHIFTSPRITE JOGADOR, 0, -1 ENDIF ELSE 'PARA BAIXO IF JOY.1 THEN IF SPRITEPOSY(JOGADOR) < 305 THEN SHIFTSPRITE JOGADOR, 0, 1 ENDIF ELSE 'START IF JOY.7 THEN LOCATE 12,12 INK 1 PRINT "=== PAUSE ===" INK 0 SLEEP 10 WHILE JOYPAD() != 128 : SLEEP 2 : WEND SLEEP 10 CLS ENDIF ENDIF ENDIF END SUB

'TILE DA RAQUETE DOS JOGADORES TILEDATA: DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG $00000000 $00022000 $00233200 $02211220 $02311320 $02311320 $02311320 $02311320 $02311320 ' Tile #0 ' Tile #0

Desenvolvimento de jogos/Programao Megadrive


DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG $02311320 $02311320 $02311320 $02311320 $02311320 $02311320 $02311320 $02311320 $02311320 $02311320 $02311320 $02311320 $02311320 $02311320 $02311320 $02311320 $02311320 $02311320 $02311320 $02211220 $00233200 $00022000 $00000000 ' Tile #1 ' Tile #2

18

Fazendo a bola ricochetear pela tela Basicamente no h nenhuma dificuldade com a linguagem aqui, mero algoritmico, qualquer programador com os conhecimentos de ifs-else consegue montar uma soluo para esse problema. A minha no foi uma das melhores, nem a mais otimizada. S um detalhe, o basiegaxorz no trabalha com numero negativo. Por isso a funo no ficou muito elegante. De todo modo, segue o fonte abaixo da funo. Essa funo est super simplria, vocs percebero, adaptem ela para criar um movimento mais "melhor" na bolinha.
'QUANDO A BOLINHA ESTIVER VINDO PRA VOC O SENTIDO X 1, OU 0 QUANDO ESTIVER INDO NA DIREO DO COMPUTADOR 'QUANDO A BOLINHA ESTIVER INDO PARA CIMA O SENTIDO Y 1, OU 0 QUANDO ESTIVER INDO PARA BAIXO GLOBAL SENTIDOX AS INTEGER GLOBAL SENTIDOY AS INTEGER

'VOC PROVAVELMENTE IR SE PERGUNTAR, QUE PORRA ESSA QUE EU FIZ... 'REALMENTE FIZ RPIDO, MAS NO TEM COMO FUGIR MUITO POIS NO TEMOS SUPORTE A VARIVEIS COM NMERO NEGATIVO. 'SE NO DAVA PARA FAZER ESSA FUNO EM BEM MENOS LINHAS, PARA SIMULAR ACABEI CRIANDO FLAGS DE SENTIDO. DECLARE SUB MOVIMENTAR_BOLA(BOLA AS INTEGER) LOCAL X AS INTEGER LOCAL Y AS INTEGER X=SPRITEPOSX(BOLA) Y=SPRITEPOSY(BOLA) 'TESTA SE NO FOI PONTO IF (X > 136) AND (X < 432) THEN 'NO FOI PONTO, VAMOS VERIFICAR SE CHEGOU EM ALGUMA PAREDE IF (Y = 139) THEN

Desenvolvimento de jogos/Programao Megadrive


'CHEGOU NA PAREDE DE CIMA, VAMOS TROCAR A DIREO DA BOLA NO EIXO Y SENTIDOY-ELSE 'TESTANDO SE CHEGOU NA PAREDE DE BAIXO IF (Y = 332) THEN 'CHEGOU, VAMOS MUDAR DE DIREO DA BOLA NO EIXO Y SENTIDOY++ ENDIF ENDIF ELSE 'FOI PONTO 'COLOCAR A BOLA NA POSIO INICIAL MOVESPRITE BOLA,278,233 'VAMOS CHAMAR A SUB QUE ATUALIZA O PLACAR E PASSAR O SENTIDOX, 'CASO ESSE SEJA IGUAL A 0 O JOGADOR FEZ UM PONTO, E SE FOR IGUAL A 1 ELE SOFREU UM PONTO. PLACAR SENTIDOX 'MUDAR O SENTIDO DA BOLA, A BOLA IR PRIMEIRO PARA O LADO DE QUEM FEZ GOL. IF SENTIDOX THEN SENTIDOX-ELSE SENTIDOX++ ENDIF ENDIF 'VAMOS MOVER A BOLA IF SENTIDOY THEN IF SENTIDOX THEN SHIFTSPRITE BOLA,-1,-1 ELSE SHIFTSPRITE BOLA,1,-1 ENDIF ELSE IF SENTIDOX THEN SHIFTSPRITE BOLA,-1,1 ELSE SHIFTSPRITE BOLA,1,1 ENDIF ENDIF END SUB

19

Reparem que eu executei uma funo PLACAR ela ainda "no existe" no seu cdigo fonte ento comente ela ou dar erro. E o nosso loop principal ficar: WHILE 1 SLEEP 1 MOVE_SPRITE JOGADOR MOVIMENTAR_BOLA BOLA WEND

Desenvolvimento de jogos/Programao Megadrive Checagem de coliso: Rebatendo a bola Coliso um assunto bem extenso. Tratar a coliso de qualquer modo algo simples, contudo, de mtodo eficiente pode ser tornar uma tarefa bem complicada, principalmente levando em considerao as limitaes do processador do genesis. Mas o que posso falar rapidamente que eu vou usar um mtodo muito especifico, que no poder ser aplicado a praticamente nenhum game. Na realidade um metodo que envolve o hardware do megadrive, o registrador de status (SR), algums emuladores (como o kega) nem implementao essa funcionalidade (passei algum tempo quebrando a cabea, at descobri que o problema no emulador). Caso queira testar seus codigos sugiro o emulador gens, muito mais fiel ao funcionamento do video-game. A funo COLLISION() utilizada no exemplo a baixo retorna o valor do SR, quando QUALQUER sprite colidir o seu valor ser igual a 1, caso contrrio igual a 0. Como nesse caso totalmente especifico no existe outra coliso possvel sem ser a bola com a raquete do pong. E em ambos os casos eu dei o mesmo tratamento, ou seja, se houver coliso inverta o sentido no eixo X. Normalmente voc nunca poder usar esse mtodo sozinho. Voc jamais saberia usando ele se, um tiro acertou voc ou se um tiro seu acertou um inimigo, ou se voc bateu em um inimigo, se um inimigo atravessou o outro na tela, se um aliado passou por voc, etc. A nica vantagem desse mtodo : no envolve nenhum processamento, o proprio hardware do mega drive faz isso. Outro detalhe, essa funo normalmente no usada por quem programa mega drive, procure ler mais sobre sprites e gerar seus mtodos ou usar algum conhecido. No proprio site do basiegaxorz nem existe a documentao dessa funo (tambm demorei um tempo para descobrir sua existncia). Eu utilizo normalmente ela como gatilho para um mtodo mais interessante. Por exemplo, se houve alguma coliso "detectar quais, onde, etc.", assim evita chamadas de um mtodo que consome mais recurso atoa. A unica alterao feita na funo de mover a bolinha foi a insero do trecho de codigo a seguir: 'VAMOS TESTAR A COLISAO DO MODO MAIS SIMPLORIO QUE EXISTE.. IF COLLISION() THEN IF SENTIDOX THEN SENTIDOX-ELSE SENTIDOX++ ENDIF ENDIF Ficando asssim:

20

'QUANDO A BOLINHA ESTIVER VINDO PRA VOC O SENTIDO X 1, OU 0 QUANDO ESTIVER INDO NA DIREO DO COMPUTADOR 'QUANDO A BOLINHA ESTIVER INDO PARA CIMA O SENTIDO Y 1, OU 0 QUANDO ESTIVER INDO PARA BAIXO GLOBAL SENTIDOX AS INTEGER GLOBAL SENTIDOY AS INTEGER

'VOC PROVAVELMENTE IR SE PERGUNTAR, QUE PORRA ESSA QUE EU FIZ... 'REALMENTE FIZ RPIDO, MAS NO TEM COMO FUGIR MUITO POIS NO TEMOS SUPORTE A VARIVEIS COM NMERO NEGATIVO. 'SE NO DAVA PARA FAZER ESSA FUNO EM BEM MENOS LINHAS, PARA SIMULAR ACABEI CRIANDO FLAGS DE SENTIDO. DECLARE SUB MOVIMENTAR_BOLA(BOLA AS INTEGER) LOCAL X AS INTEGER LOCAL Y AS INTEGER X=SPRITEPOSX(BOLA) Y=SPRITEPOSY(BOLA) 'TESTA SE NO FOI PONTO

Desenvolvimento de jogos/Programao Megadrive


IF (X > 136) AND (X < 432) THEN 'NO FOI PONTO, VAMOS VERIFICAR SE CHEGOU EM ALGUMA PAREDE IF (Y = 139) THEN 'CHEGOU NA PAREDE DE CIMA, VAMOS TROCAR A DIREO DA BOLA NO EIXO Y SENTIDOY-ELSE 'TESTANDO SE CHEGOU NA PAREDE DE BAIXO IF (Y = 332) THEN 'CHEGOU, VAMOS MUDAR DE DIREO DA BOLA NO EIXO Y SENTIDOY++ ENDIF ENDIF ELSE 'FOI PONTO 'COLOCAR A BOLA NA POSIO INICIAL MOVESPRITE BOLA,278,233 'VAMOS CHAMAR A SUB QUE ATUALIZA O PLACAR E PASSAR O SENTIDOX, 'CASO ESSE SEJA IGUAL A 0 O JOGADOR FEZ UM PONTO, E SE FOR IGUAL A 1 ELE SOFREU UM PONTO. PLACAR SENTIDOX 'MUDAR O SENTIDO DA BOLA, A BOLA IR PRIMEIRO PARA O LADO DE QUEM FEZ GOL. IF SENTIDOX THEN SENTIDOX-ELSE SENTIDOX++ ENDIF ENDIF 'VAMOS TESTAR A COLISAO DO MODO MAIS SIMPLORIO QUE EXISTE.. IF COLLISION() THEN IF SENTIDOX THEN SENTIDOX-ELSE SENTIDOX++ ENDIF ENDIF 'VAMOS MOVER A BOLA IF SENTIDOY THEN IF SENTIDOX THEN SHIFTSPRITE BOLA,-1,-1 ELSE SHIFTSPRITE BOLA,1,-1 ENDIF ELSE IF SENTIDOX THEN SHIFTSPRITE BOLA,-1,1 ELSE SHIFTSPRITE BOLA,1,1 ENDIF

21

Desenvolvimento de jogos/Programao Megadrive


ENDIF END SUB

22

Marcando a pontuao Duas funes aqui, a funo "placar" que o exemplo acima est usando. E uma funo para reiniciar o jogo, apos o placar atingir 10.
'NADA DE MAIS AQUI, S VARIAVEIS GLOBAIS PARA MARCAR A PONTUAO DE CADA JOGADOR GLOBAL PONTOS_JOGADOR AS INTEGER GLOBAL PONTOS_CPU AS INTEGER

'FUNO QUE ATUALIZA O PLACAR DECLARE SUB PLACAR(PONTO AS INTEGER) 'MUDA O PADRO DE ESCRITA PARA O PLANO SCROLL_B 'O PAUSE, EST NO PLANO SCROLL_A, E QUANDO EU REMOVO O PAUSE EU DEI UM CLS NO PLANO. 'ESTOU MUDANDO DE PLANO PARA ESCREVER O PLACAR S PARA QUANDO O JOGO FOR DESPAUSADO NO LIMPAR O PLACAR JUNTO SETTEXTPLANE SCROLL_B 'CIANO INK 1 'TESTA DE QUEM FOI PONTO IF PONTO THEN 'CPU LOCATE 1,19 PONTOS_CPU++ PRINT PONTOS_CPU 'VOC PERDE O JOGO SE O CPU TIVER 10 PONTOS IF PONTOS_CPU > 9 THEN LOCATE 12,8 PRINT "PERDEU, APERTE START" INK 0 WHILE JOYPAD() != 128 : SLEEP 2 : WEND RESET ENDIF ELSE 'JOGADOR LOCATE 1,17 PONTOS_JOGADOR++ PRINT PONTOS_JOGADOR 'VOC GANHA O JOGO COM SE TIVER 10 PONTOS IF PONTOS_JOGADOR > 9 THEN LOCATE 12,8 PRINT "GANHOU, APERTE START" INK 0 WHILE JOYPAD() != 128 : SLEEP 2 : WEND RESET ENDIF ENDIF 'RETORNA A COR ORIGINAL

Desenvolvimento de jogos/Programao Megadrive


INK 0 'VOLTA A ESCRITA PADRO NO PLANO DE CIMA SETTEXTPLANE SCROLL_A END SUB

23

Funo para reiniciar o jogo, ela usa um Label, chamado "inicio". DECLARE SUB RESET() PONTOS_JOGADOR=0 PONTOS_CPU=0 SENTIDOX=0 SENTIDOY=0 FREEALLSPRITES SETTEXTPLANE SCROLL_A CLS SETTEXTPLANE SCROLL_B CLS GOTO INICIO END Eu inseri o label logo antes da funo que desenha a tela, assim: 'EXECUTA A SUB QUE APRESENTAR A TELA DE APRESENTAO DO JOGO APRESENTACAO 'LABEL QUE INDICA INICIO DO JOGO INICIO SLEEP 10 'EXECUTA A SUB QUE IR DESENHAR A TELA DO PONG DESENHA_TELA Inteligncia artificial bsica: Jogador 1 versus CPU IA horrivel, praticamente impossivel passar do CPU. Fiz mais para vocs terem uma noo do jogo funcionando mesmo. Com o movimento desse jeito da bolinha creio que simplesmente impossivel passar algo pelo CPU. Mas ai est. 'OK, IA HORRIVEL :P 'FIZ S PARA VEREM O JOGO FUNCIONANDO DECLARE SUB MOVE_CPU(CPU AS INTEGER, BOLA AS INTEGER) LOCAL BOLAY AS INTEGER LOCAL CPUY AS INTEGER BOLAY=SPRITEPOSY(BOLA) CPUY=SPRITEPOSY(CPU) IF BOLAY > CPUY THEN IF CPUY < 305 THEN SHIFTSPRITE CPU,0,1 ENDIF ELSE IF BOLAY < CPUY THEN IF CPUY > 142 THEN SHIFTSPRITE CPU,0,-1

Desenvolvimento de jogos/Programao Megadrive ENDIF ENDIF ENDIF END SUB Nosso loop principal ficou assim: WHILE 1 SLEEP 1 MOVE_SPRITE JOGADOR MOVIMENTAR_BOLA BOLA MOVE_CPU CPU,BOLA WEND Pong completo S para postar como ficou o jogo completo, com ia horrivel, e movimento da bola ruim. Modifique e faa um pong melhor.
'IGNORA AS OPES DE COMPILAO DA GUI, E COMPILA O JOGO PARA MEGA DRIVE (CARTUCHO) OPTION CARTRIDGE 'OBRIGA EXPLICITAMENTE A DECLARAO DE VARIVEIS (BOAS PRTICA) OPTION EXPLICIT 'DESABILITA A SENSIBILIDADE A CAIXA ALTA PARA VARIAVEIS, LABELS, FUNCES, ETC. OPTION CASESENSE 'TTULO QUE SER EXIBIDO NA JANELA DO SEU EMULADOR. (DEPOIS TITULO INSERIDO AUTOMATICAMENTE PELO BASIEGAXORZ) OPTION TITLE, "PONG!"

24

'ATRIBUI OS COMANDOS DE DRAW PARA O PLANO SCROLL_B POR PADRO, E OS DE TEXTO AO PLANO SCROLL_A SETGFXPLANE SCROLL_B SETTEXTPLANE SCROLL_B

'EXECUTA A SUB QUE APRESENTAR A TELA DE APRESENTAO DO JOGO APRESENTACAO 'LABEL QUE INDICA INICIO DO JOGO INICIO SLEEP 10 'EXECUTA A SUB QUE IR DESENHAR A TELA DO PONG DESENHA_TELA

'ALTERA O PADRO TO TEXTO PARA O SCROLL_A

SETTEXTPLANE SCROLL_A 'ADICIONAR OS SPRITES DOS JOGADORES E A BOLA DIM JOGADOR AS INTEGER DIM CPU AS INTEGER DIM BOLA AS INTEGER

JOGADOR=ADDSPRITE(4,1) CPU=ADDSPRITE(4,1)

Desenvolvimento de jogos/Programao Megadrive


BOLA=ADDSPRITE(1,1)

25

'ALOCA OS SPRITES DOS JOGADORES LOADTILES TILEDATA, 4, 256

'INSERE DUAS CORES NA PALETA DE COR (DOIS TONS DE CINZA) PALLETTE 2184, 0, 2 PALLETTE 3276, 0, 3

'ATRIBUI EM QUAL REGIO DA MEMRIA O INICIO DO SPRITE\ PROPSPRITE JOGADOR,256, 0 PROPSPRITE CPU,256, 0 PROPSPRITE BOLA,7,2

'POSICIONA OS SPRITES NA TELA MOVESPRITE JOGADOR, 136, 218 MOVESPRITE CPU, 432,218 MOVESPRITE BOLA, 278,233

'LOOP DO JOGO 'VOU REMOVER TUDO DO LOOP WHILE 1 SLEEP 1 MOVE_SPRITE JOGADOR MOVIMENTAR_BOLA BOLA MOVE_CPU CPU,BOLA WEND

'FUNO QUE DESENHA A TELA (REDE, LATERAIS, JOGADORES) DECLARE SUB DESENHA_TELA() 'DECLARA A VARIVEL DENTRO DA FUNO COMO LOCAL, A MEMRIA SER LIBERADA APS O TERMINO DA FUNO (BOA PRTICA) LOCAL I AS INTEGER 'ITERA UMA VEZ PARA CADA COLUNA FOR I=1 TO 38 'AS POSIES DE MEMRIA ANTES DE 256 SO RESERVADAS PARA OS CARATERES. 'IMPRIME A LINHA SUPERIOR DRAWTILE 205,I,1 'IMPRIME A LINHA INFERIOR DRAWTILE 205,I,26 NEXT FOR I=2 TO 25 'IMPRIME A LINHA VERTICAL DRAWTILE 186, 19, I NEXT 'MOVE O CURSOR DE TEXTO PARA A POSIO 0,1 (O COMANDO LOCATE USA AS COORDENADAS Y,X E NO X,Y) LOCATE 1,0 'MUDA A COR PARA VERDE

Desenvolvimento de jogos/Programao Megadrive


INK 2 PRINT "JOGADOR" LOCATE 1,35 PRINT "CPU" INK 1 'IMPRIME O PLACAR ZERADO LOCATE 1,17 PRINT 0 LOCATE 1, 19 PRINT 0 'VOLTA A COR ORIGINAL INK 0 END SUB

26

'FUNO QUE IMPRIME A TELA INICIADO DO JOGO E PRESSIONAR START PARA SEGUIR EM FRENTE DECLARE SUB APRESENTACAO() LOCATE 10,10 'MUDA A COR DO TEXTO PARA VERDE INK 2 PRINT "PONG - PRESS START" 'VOLTA A COR ORIGINAL INK 0 'EXECUTA UMA ESPERA AT QUE O BOTO DE START SEJA PRESSIONADO. (USE O COMANDO SLEEP (BOA PRTICA)) WHILE JOYPAD() != 128 : SLEEP 2 : WEND CLS END SUB

'TESTA E MOVE O SPRITE DO JOGADOR, SE O MOVIMENTO FOR PERMITIDO DECLARE SUB MOVE_SPRITE(JOGADOR AS INTEGER) LOCAL JOY AS INTEGER JOY = JOYPAD() 'PARA CIMA IF JOY.0 THEN IF SPRITEPOSY(JOGADOR) > 142 THEN SHIFTSPRITE JOGADOR, 0, -1 ENDIF ELSE 'PARA BAIXO IF JOY.1 THEN IF SPRITEPOSY(JOGADOR) < 305 THEN SHIFTSPRITE JOGADOR, 0, 1 ENDIF ELSE 'START IF JOY.7 THEN LOCATE 12,12 INK 1

Desenvolvimento de jogos/Programao Megadrive


PRINT "=== PAUSE ===" INK 0 SLEEP 10 WHILE JOYPAD() != 128 : SLEEP 2 : WEND SLEEP 10 CLS ENDIF ENDIF ENDIF END SUB

27

'QUANDO A BOLINHA ESTIVER VINDO PRA VOC O SENTIDO X 1, OU 0 QUANDO ESTIVER INDO NA DIREO DO COMPUTADOR 'QUANDO A BOLINHA ESTIVER INDO PARA CIMA O SENTIDO Y 1, OU 0 QUANDO ESTIVER INDO PARA BAIXO GLOBAL SENTIDOX AS INTEGER GLOBAL SENTIDOY AS INTEGER

'VOC PROVAVELMENTE IR SE PERGUNTAR, QUE PORRA ESSA QUE EU FIZ... 'REALMENTE FIZ RPIDO, MAS NO TEM COMO FUGIR MUITO POIS NO TEMOS SUPORTE A VARIVEIS COM NMERO NEGATIVO. 'SE NO DAVA PARA FAZER ESSA FUNO EM BEM MENOS LINHAS, PARA SIMULAR ACABEI CRIANDO FLAGS DE SENTIDO. DECLARE SUB MOVIMENTAR_BOLA(BOLA AS INTEGER) LOCAL X AS INTEGER LOCAL Y AS INTEGER X=SPRITEPOSX(BOLA) Y=SPRITEPOSY(BOLA) 'TESTA SE NO FOI PONTO IF (X > 136) AND (X < 432) THEN 'NO FOI PONTO, VAMOS VERIFICAR SE CHEGOU EM ALGUMA PAREDE IF (Y = 139) THEN 'CHEGOU NA PAREDE DE CIMA, VAMOS TROCAR A DIREO DA BOLA NO EIXO Y SENTIDOY-ELSE 'TESTANDO SE CHEGOU NA PAREDE DE BAIXO IF (Y = 332) THEN 'CHEGOU, VAMOS MUDAR DE DIREO DA BOLA NO EIXO Y SENTIDOY++ ENDIF ENDIF ELSE 'FOI PONTO 'COLOCAR A BOLA NA POSIO INICIAL MOVESPRITE BOLA,278,233 'VAMOS CHAMAR A SUB QUE ATUALIZA O PLACAR E PASSAR O SENTIDOX, 'CASO ESSE SEJA IGUAL A 0 O JOGADOR FEZ UM PONTO, E SE FOR IGUAL A 1 ELE SOFREU UM PONTO. PLACAR SENTIDOX 'MUDAR O SENTIDO DA BOLA, A BOLA IR PRIMEIRO PARA O LADO DE QUEM FEZ GOL. IF SENTIDOX THEN SENTIDOX--

Desenvolvimento de jogos/Programao Megadrive


ELSE SENTIDOX++ ENDIF ENDIF 'VAMOS TESTAR A COLISAO DO MODO MAIS SIMPLORIO QUE EXISTE.. IF COLLISION() THEN IF SENTIDOX THEN SENTIDOX-ELSE SENTIDOX++ ENDIF ENDIF 'VAMOS MOVER A BOLA IF SENTIDOY THEN IF SENTIDOX THEN SHIFTSPRITE BOLA,-1,-1 ELSE SHIFTSPRITE BOLA,1,-1 ENDIF ELSE IF SENTIDOX THEN SHIFTSPRITE BOLA,-1,1 ELSE SHIFTSPRITE BOLA,1,1 ENDIF ENDIF END SUB

28

'NADA DE MAIS AQUI, S VARIAVEIS GLOBAIS PARA MARCAR A PONTUAO DE CADA JOGADOR GLOBAL PONTOS_JOGADOR AS INTEGER GLOBAL PONTOS_CPU AS INTEGER

'FUNO QUE ATUALIZA O PLACAR DECLARE SUB PLACAR(PONTO AS INTEGER) 'MUDA O PADRO DE ESCRITA PARA O PLANO SCROLL_B 'O PAUSE, EST NO PLANO SCROLL_A, E QUANDO EU REMOVO O PAUSE EU DEI UM CLS NO PLANO. 'ESTOU MUDANDO DE PLANO PARA ESCREVER O PLACAR S PARA QUANDO O JOGO FOR DESPAUSADO NO LIMPAR O PLACAR JUNTO SETTEXTPLANE SCROLL_B 'CIANO INK 1 'TESTA DE QUEM FOI PONTO IF PONTO THEN 'CPU LOCATE 1,19 PONTOS_CPU++ PRINT PONTOS_CPU 'VOC PERDE O JOGO SE O CPU TIVER 10 PONTOS

Desenvolvimento de jogos/Programao Megadrive


IF PONTOS_CPU > 9 THEN LOCATE 12,8 PRINT "PERDEU, APERTE START" INK 0 WHILE JOYPAD() != 128 : SLEEP 2 : WEND RESET ENDIF ELSE 'JOGADOR LOCATE 1,17 PONTOS_JOGADOR++ PRINT PONTOS_JOGADOR 'VOC GANHA O JOGO COM SE TIVER 10 PONTOS IF PONTOS_JOGADOR > 9 THEN LOCATE 12,8 PRINT "GANHOU, APERTE START" INK 0 WHILE JOYPAD() != 128 : SLEEP 2 : WEND RESET ENDIF ENDIF 'RETORNA A COR ORIGINAL INK 0 'VOLTA A ESCRITA PADRO NO PLANO DE CIMA SETTEXTPLANE SCROLL_A END SUB

29

'FUNO QUE REINICIA O JOGO, ZERA O PLACAR, LIMPA A TELA, LIBERA OS SPRITES DECLARE SUB RESET() PONTOS_JOGADOR=0 PONTOS_CPU=0 SENTIDOX=0 SENTIDOY=0 FREEALLSPRITES SETTEXTPLANE SCROLL_A CLS SETTEXTPLANE SCROLL_B CLS GOTO INICIO END

'OK, IA HORRIVEL :P 'FIZ S PARA VEREM O JOGO FUNCIONANDO DECLARE SUB MOVE_CPU(CPU AS INTEGER, BOLA AS INTEGER) LOCAL BOLAY AS INTEGER LOCAL CPUY AS INTEGER BOLAY=SPRITEPOSY(BOLA)

Desenvolvimento de jogos/Programao Megadrive


CPUY=SPRITEPOSY(CPU) IF BOLAY > CPUY THEN IF CPUY < 305 THEN SHIFTSPRITE CPU,0,1 ENDIF ELSE IF BOLAY < CPUY THEN IF CPUY > 142 THEN SHIFTSPRITE CPU,0,-1 ENDIF ENDIF ENDIF END SUB

30

'TILE DA RAQUETE DOS JOGADORES TILEDATA: DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG DATALONG $00000000 $00022000 $00233200 $02211220 $02311320 $02311320 $02311320 $02311320 $02311320 $02311320 $02311320 $02311320 $02311320 $02311320 $02311320 $02311320 $02311320 $02311320 $02311320 $02311320 $02311320 $02311320 $02311320 $02311320 $02311320 $02311320 $02311320 $02311320 $02211220 $00233200 $00022000 ' Tile #1 ' Tile #2 ' Tile #0 ' Tile #0

Desenvolvimento de jogos/Programao Megadrive


DATALONG $00000000

31

Intermedirio Avanado
Descrio das portas de I/O do Mega Drive
VDP $C00000 (Porta de dados) $C00004 (Porta de controle) Leitura
* * * * * * VAZIO CHEIO PAL

F SOVR C IMPAR

VB HB

VAZIO CHEIO F SOVR

1: 0: 1: 0: 1: 1:

FIFO de escrita vazio FIFO de escrita cheio

IMPAR VB HB DMA PAL

Ocorreu interrupo vertical Ocorreu estouro de sprites. Muitos na mesma linha. Mais de 17 no modo de 32 clulas. Mais de 21 no modo de 40 clulas. 1: Ocorreu coliso entre dois pixels no nulos entre dois sprites. 0: 1: Quadro mpar no modo entrelaado. 0: Quadro par no modo entrelaado. 1: Durante o "blanking" vertical 0: 1: Durante o "blanking" horizontal 0: 1: Realizando DMA 0: 1: Modo PAL 0: Modo NTSC

Escrita 1: Enviar dados ao registrador


1 0 0 RS4 RS3 RS2 RS1 RS0 D3 D2 D1 D0

D7 D6 D5 D4

RS4 ~ RS0 D7 ~ D0

: Nmero do registrador : Dados a enviar

As portas do VDP devem ser acessadas via "word" ou "long word", para correto funcionamento.

Desenvolvimento de jogos/Programao Megadrive Escrita 2: Seleo de endereo 1 Escrita


CD1 CD0 A13 A12 A11 A10 A9 A8 A7 A6 A5 A4 A3 A2 A1 A0

32

2 Escrita
0 0 0 0 0 0 0 0

CD5 CD4 CD3 CD2 0 0 A15 A14

CD5 ~ CD0 A15 ~ A0

: :

Cdigo de indentificao Endereo de destino


CD5 CD4 CD3 CD2 CD1 CD0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 1 0 1 0 0 0 0 1 1 1 0 0 0

Modo de Acesso Escrita em VRAM Escrita em CRAM

Escrita em VSRAM 0 Leitura da VRAM Leitura da CRAM 0 0

Leitura da VSRAM 0

$C00008 (Contador horizontal/vertical) Modo no entrelaado


VC7 VC6 VC5 VC4 VC3 VC2 VC1 VC0 HC8 HC7 HC6 HC5 HC4 HC3 HC2 HC1

Modo entrelaado
VC7 VC6 VC5 VC4 VC3 VC2 VC1 VC8 HC8 HC7 HC6 HC5 HC4 HC3 HC2 HC1

HC8 ~ HC1 VC8 ~ VC0 Registradores

: :

Posio horizontal Posio vertical

REG 0: Registrador de modo nmero 1


0 0 0 IE1 0 1 M3 0

IE1 M3

1: 0: 1: 0:

Habilita interrupo horizontal (68000 nvel 4) Desabilita interrupo horizontal (REG #10) Parar o contador HV Habilita o contador HV para leitura

REG 1: Registrador de modo nmero 2


0 DISP IE0 M1 M2 1 0 0

Desenvolvimento de jogos/Programao Megadrive

33

DISP IE0 M1 M2

1: 0: 1: 0: 1: 0: 1: 0:

Habilita display Desabilita display Habilita interrupo vertical (68000 nvel 6) Desabilita interrupo vertical Habilita DMA Desabilita DMA Modo 30 clulas na horizontal (modo PAL) Modo 28 clulas na horizontal (Modo PAL, sempre 0 em modo NTSC)

REG 2: Endereo base do mapa do fundo A


0 0 SA15 SA14 SA13 0 0 0

Endereo da VRAM: $XXX0_0000_0000_0000 REG 3: Endereo base do mapa da janela


0 0 WD15 WD14 WD13 WD12 WD11 0

WD11 deve ser 0 no modo de 40 clulas horizontais Endereo da VRAM: $XXXX_X000_0000_0000 (32 clulas horizontais) Endereo da VRAM: $XXXX_0000_0000_0000 (40 clulas horizontais) REG 4: Endereo base do mapa do fundo B
0 0 0 0 0 SB15 SB14 SB13

Endereo da VRAM: $XXX0_0000_0000_0000 REG 5: Endereo base da tabela de atributos dos sprites
0 AT15 AT14 AT13 AT12 AT11 AT10 AT9

WD9 deve ser 0 no modo de 40 clulas horizontais Endereo da VRAM: $XXXX_XXX0_0000_0000 (32 clulas horizontais) Endereo da VRAM: $XXXX_XX00_0000_0000 (40 clulas horizontais) REG 7: Cor do fundo
0 0 CPT1 CPT0 COL3 COL2 COL1 COL0

CPT1 ~ CPT0 : Nmero da palheta COL3 ~ COL0 : Cdigo da cor REG 10: Interrupo horizontal
BIT7 BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0

Conta o nmero da linha horizontal da tela sendo atualmente renderizado

REG 11: Registrador de modo nmero 3

Desenvolvimento de jogos/Programao Megadrive

34

0 0 0 0 IE2 VSCR HSCR LSCR

IE2

1: 0:

Habilita interrupo externa (68000 nvel 2) Desabilita interrupo externa

Modo de deslocamento horizontal


VSCR Funo 0 1 Scroll completo Scroll a cada duas clulas

Modo de deslocamento vertical


HSCR LSCR Funo 0 0 1 1 0 1 0 1 Scroll completo Invlido Scroll clula a clula Scroll linha a linha

REG 12: Registrador de modo nmero 4


RS0 0 0 0 S/TE LSM1 LSM0 RS1

RS0

0: Modo de 32 clulas horizontais 1: Modo de 40 clulas horizontais RS1 0: Modo de 32 clulas horizontais 1: Modo de 40 clulas horizontais * recomendvel setar o mesmo valor para RS0 e RS1. S/TE 1: Habilita sombreamento e realce 0: Habilita sombreamento e realce LSM1, LSM0: Modo de entrelaamento
LSM1 LSM2 Funo 0 0 1 1 0 1 0 1 Sem entrelaamento Entrelaado Invlido Entrelaado (Dupla resoluo)

REG 13: Endereo da tabela de deslocamento horizontal


0 0 HS15 HS14 HS13 HS12 HS11 HS10

Endereo da VRAM: $XXXX_XX00_0000_0000 REG 15: Dados de auto incremento A cada vez que a CPU acessa a memria da VDP do Mega Drive, a posio atual desta memria incrementada. Este registrador define o tamanho do incremento.

Desenvolvimento de jogos/Programao Megadrive

35

0 0 HS15 HS14 HS13 HS12 HS11 HS10

INC7 ~ INC0: Tamanho do incremento ( 0 ~ $FF ) REG 16: Tamanho do plano de fundo
0 0 VSZ1 VSZ0 0 0 HSZ1 HSZ0

VSZ1 VSZ0 Funo 0 0 1 1 0 1 0 1 32 clulas na vertical 64 clulas na vertical Invlido 128 clulas na vertical

HSZ1 HSZ0 Funo 0 0 1 1 0 1 0 1 32 clulas na horizontal 64 clulas na horizontal Invlido 128 clulas na horizontal

REG 17: Posio horizontal da janela


RIGT 0 0 WHP5 WHP4 WHP3 WHP2 WHP1

RIGT

0: Janela est esquerda do ponto base 1: Janela est direita do ponto base WHP5 ~ WHP1 Posio horizontal em clulas, isto de 8 em 8 pixels REG 18: Posio vertical da janela
DOWN 0 0 WVP4 WVP3 WVP2 WVP1 WVP0

DOWN

0 : Janela est acima do ponto base 1 : Janela est abaixo do ponto base WVP4 ~ WVP0 Posio vertical em clulas REG 19: Byte menos significativo do contador de DMA
LG7 LG6 LG5 LG4 LG3 LG2 LG1 LG0

REG 20: Byte mais significativo do contador de DMA


LG15 LG14 LG13 LG12 LG11 LG10 LG9 LG8

REG 21: Poro inferior do endereo de origem de DMA


SA8 SA7 SA6 SA5 SA4 SA3 SA2 SA1

REG 22: Poro central do endereo de origem de DMA

Desenvolvimento de jogos/Programao Megadrive

36

SA16 SA15 SA14 SA13 SA12 SA11 SA10 SA9

REG 23: Poro superior do endereo de origem de DMA


DMD1 DMD0 SA22 SA21 SA20 SA19 SA18 SA17

SA22 ~ SA1 : DMD1, DMD0 :

Endereo de origem de DMA Modo de DMA


DMD1 DMD0 Funo 0 1 1 SA23 0 1 Memria para vdeo Preenche VRAM Vdeo para vdeo

Exemplo de utilizao das portas void init_GFX() { register unsigned int *pw; pw = (uint *) 0xC00004; /* Aponta para a porta de controle */ *pw = 0x8016; /* reg. 0 - Habilita HBL */ *pw = 0x8174; /* reg. 1 - Habilita display, VBL, DMA e seta a largura */ *pw = 0x8230; /* reg. 2 - Plano A =$30*$400=$C000 */ *pw = 0x832C; /* reg. 3 - Janela =$2C*$400=$B000 */ *pw = 0x8407; /* reg. 4 - Plano B =$7*$2000=$E000 */ *pw = 0x855E; /* reg. 5 - Tabela de sprites em $BC00=$5E*$200 */ *pw = 0x8700; /* reg. 7 - Cor do fundo */ *pw = 0x8a01; /* reg 10 - HInterrupt timing */ *pw = 0x8b00; /* reg 11 - $0000abcd a=interrupo externa b=scroll horiz. cd=scroll vert. */ *pw = 0x8c81; /* reg 12 - clulas horiz + sombreamento/realce + modo entrelaamento (40 clulas, sem sombreamento, sem entrelaamento)*/ *pw = 0x8d2E; /* reg 13 - Tabela de deslocamento horizontal = $B800 */ *pw = 0x8f02; /* reg 15 - auto incremento */ *pw = 0x9011; /* reg 16 - tamanho dos planos de fundo (64x64) */ *pw = 0x9100; /* reg 17 - posio horizontal da janela */ *pw = 0x92ff; /* reg 18 - posio vertical da janela */ };

Desenvolvimento de jogos/Programao Megadrive

37

Programao assembly 68k


Documentao Assembly A extensa documentao do assembly do 68k pode ser encontrada no Devega [9]. Cabealho da ROM O cabealho da ROM para Mega Drive consiste de duas sees, cada uma de 256 bytes. A primeira "exigida" pelo processador, e indicam o incio da pilha, o endereo da rotina principal e os endereos das rotinas de excees (traps) e interrupes. J a segunda seo uma padronizao realizada pela SEGA para identificao do cartucho (direitos autorais, nome do produto, etc.) e informaes sobre utilizao de recursos do hardware (mapeamento de memria, perifricos, etc.).

Os elementos mais usados do Vetor de Excees (primeiros 256 bytes)


Item Endereo 1 2 26 28 30 Descrio

0x000000 Endereo do incio da pilha (geralmente prximo ao fim da memria RAM) 0x000004 Endereo da rotina principal (valor inicial do PC, tambm para quando resetado) 0x000068 Interrupo de nvel 2: no Mega Drive, Externa. 0x000070 Interrupo de nvel 4: no Mega Drive, Retrao Horizontal. 0x000078 Interrupo de nvel 6: no Mega Drive, Retrao Vertical.

O contedo de cada elemento do Vetor de Excees o endereo absoluto (em relao ao primeiro byte do arquivo binrio) da respectiva rotina de tratamento da exceo. Cada elemento consiste de 4 bytes. O costume , quando for desejado no tratar certas excees, elas reiniciem o software, ou seja, apontem para o comeo do programa. Vale destacar que as interrupes de retrao devem ser tratadas, nem que seja no fazer nada, j que so efetivamente geradas a tempo constante. As demais excees/interrupes no citadas podem ser encontradas no Apndice B do MOTOROLA M68000 FAMILY Programmer's Reference Manual disponvel no Devega [9].

Referncias
[1] [2] [3] [4] [5] [6] [7] [8] [9] http:/ / www. gnu. org/ software/ binutils/ http:/ / devster. monkeeh. com/ sega/ basiegaxorz/ http:/ / www. chez. com/ kaneda/ index. php http:/ / www. classicgaming. com/ epr/ genesis. htm http:/ / home. hiwaay. net/ ~eubanks/ http:/ / gamesprite. files. wordpress. com/ 2008/ 01/ iris. gif http:/ / pomoti. com/ wp-content/ uploads/ 2008/ 10/ pong. jpg http:/ / www. abusar. org/ images/ ascii. gif http:/ / www. emulationzone. org/ projects/ metalix/ 68kmanuals. htm

Fontes e Editores da Pgina

38

Fontes e Editores da Pgina


Desenvolvimento de jogos/Programao Megadrive Fonte: http://pt.wikibooks.org/w/index.php?oldid=226633 Contribuidores: Defender, Haroldoop, Helder.wiki, Jorge Morais, Marcos Antnio Nunes de Moura, Rodolforg, Wutsje, 40 edies annimas

Licena
Creative Commons Attribution-Share Alike 3.0 Unported //creativecommons.org/licenses/by-sa/3.0/