Upload
helton-mori
View
125
Download
2
Embed Size (px)
Citation preview
Desenvolvimento de jogos/Programação Megadrive 1
Desenvolvimento de jogos/ProgramaçãoMegadrive
IntroduçãoEste wikibook destina-se àqueles que estejam interessados no desenvolvimento de jogos para o videogameconhecido como Mega Drive.(Em construção)
Ferramentas
Montadores
Também conhecidos pelo termo inglês assemblers, geram o código de máquina referente ao código fonte escrito nalinguagem de montagem (assembly). No caso do Mega Drive, o código é escrito para os processadores Motorola68000 (também 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 genérico quanto a processador. Sua sintaxesegue o padrão AT&T em vez do da Intel. Caso seja necessário compilar o GAS para o M68k, utilize os seguintescomandos:
./configure -target=m68k-coff
make
O primeiro comando configura o alvo de montagem ser o processador família M68k, sem sistema operacional. Osegundo efetivamente compila os programas componentes do GAS, que são:•• addr2line•• ar•• as•• cxxfilt•• ld•• nm•• objcopy•• objdump•• ranlib•• readelf•• size•• strings•• stripOs mais usados, para fins de programas para Mega Drive, são o as (o montador/assembler), o ld (o ligador/linker) eo objcopy (para gerar o arquivo no formato binário correto).
Desenvolvimento de jogos/Programação Megadrive 2
Usando o as
as -m68000 -o arquivo.o arquivo.s
É importante o uso do parâmetro -m68000, porque o padrão é 68020. O parâmetro -o serve para definir o nome doarquivo objeto de saída (o padrão é "a.out"). Por fim, o não opcional: o código-fonte.
Usando o ld
Após feita as compilações de todas os códigos do programa, é preciso ligá-los.
ld --oformat=binary -Ttext=0 -o rom.bin arquivo.o [outros .o]
• --oformat=binary e -Ttext=0 são necessários para o correto formato do arquivo binário.• -o, como já mencionado para o as, define o nome do arquivo binário de saída, no caso "rom.bin"• O parâmetro obrigatório para o ld é, obviamente, o(s) arquivo(s) objeto(s) que compõe o programa.
Compiladores
BasiEgaXorz
Compilador de BASIC para Mega Drive, muito fácil 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 dalinguagem C, (Sintaxe K&R, para ser mais exato), ele é extremamente simples de usar, bastando descompactar eusar, além de já vir com alguns exemplos simples.Pode ser baixado deste site [3], ou deste [4]
GCC68k - GNU C Compiler for 68k
Versão do GNU C adaptado para o processador MC68000. Suporta tanto C como C++, podendo também suportaroutras linguagens, como Fortran, Pascal e outros, dependendo da configuração. Tem a desvantagem de serligeiramente mais difícil de usar do que o SGCC.Neste site [5], você pode baixar uma versão deste compilador já preparada para o Mega Drive.
BásicoPara os exemplos desta seção, será utilizado o BasiEgaXorz, por ser mais simples de usar.
Desenvolvimento de jogos/Programação Megadrive 3
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, selecionáveis 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 <código RGB>, <n° da palheta>, <n° da cor>
• <código RGB> é um número hexadecimal que repesenta os tons de vermelho, verde e azul que compõem a cordesejada. Para calcular o código equivalente à cor, utilize a fórmula (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 número da palheta que se deseja modificar• <n° da cor> indica qual das cores desta palheta será alteradaExemplo:
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 "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 usuário pressionar qualquer botão dojoystick, e então altera a cor 1 de cada palheta, a qual corresponde à cor utilizada pelo texto; como consequência, otexto muda de cor.
Desenvolvimento de jogos/Programação Megadrive 4
PALLETTES pode setar várias cores de uma determinada palheta de uma só vez. A sua sintaxe é:
Pallettes <rótulo dos dados>, <n° da palheta>, <cor inicial>, <n° de cores>, [Deslocamento]
• <rótulo dos dados> indica qual rótulo de dados será lido para definir as cores da palheta indicada (veja oexemplo abaixo para entender melhor)
• <n° da palheta> número da palheta que será alterada• <cor inicial> cor inicial a ser alterada. Por exemplo, se a cor inicial for 4 e o número de cores for 3, serão
alteradas as cores 4, 5 e 6• <n° de cores> o número de cores que serão alteradas• [Deslocamento] parâmetro opcional que indica a posição dentro dos dados indicados pelo rótulo a partir da qual
os dados serão 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 "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/Programação Megadrive 5
No exemplo acima, pallette1, palette2, palette3 e palette4 são rótulos que apontam para dados, os quais, neste caso,são definidos pelo comando DATAINT. O cifrão na frente de cada número serve para indicar que o número emquestão está em notação hexadecimal. Isso torna mais fácil visualizar a cor que está sendo definida, visto que os trêsúltimos dígitos do código da cor em hexa correspondem justamente aos valores de azul, verde e vermelho,respectivamente. Observe, também, que a cor do fundo também foi alterada, porque a cor zero da palheta zerotambém mudou.Importante: Se for copiar e colar este exemplo para o BasiEgaXorz, lembre-se de tirar o espaço à esquerda dosrótulos, mas apenas dos rótulos. Isto é necessário, porque o BasiEgaXorz pressupõe que qualquer linha que comececom um ou mais espaços à esquerda não contenha um rótulo.
Lendo o joystick
Existem algumas funções para o BasiEgaXorz que fazem o software interagir com o joystick, vou lista-lasprimeiramente, e a seguir dou um exemplo mais prático.
WaitPadUp <# do controle>
Espera que o device do numero especificado seja ligado ao console. Você pode fazer o jogo pausar se o controle forremovido, ou caso o jogador selecione a opção de 2 players, verificar a existencia de um segundo controle paraprosseguir.Importante: os valores para o primeiro e o segundo controle são 0 e 1 respectivamente.
Joypad(<# do controle>)
Essa função de longe é a mais importante para interação com o controle. Essa função retorna o bit do eventocorrespondente. A tabela a baixo mostra a relação de Bit-Evento.
Bit Hex Decimal Evento
0 &h001 1 Cima
1 &h002 2 Baixo
2 &h004 4 Esquerda
3 &h008 8 Direita
4 &h010 16 B
5 &h020 32 C
6 &h040 64 A
7 &h080 128 Start
8 &h100 256 Z (6-Botões)
9 &h200 512 Y (6-Botões)
10 &h400 1024 X (6-Botões)
11 &h800 2048 Mode (6-Botões)
Não vou entrar muito em detalhes, vocês podem procurar no site da BasiEgaXorz por uma documentação maisdetalhada, mas quando se utiliza joystick de 3 botoes os bits referentes aos botões ZYX não estarão 'limpos', e simtera um valor randomico qualquer, I.E, lixo. Tomar cuidado com isso.Vamos ao exemplo:
Desenvolvimento de jogos/Programação Megadrive 6
Cole o exemplo abaixo no BasiEgaXorz, lembrando que deve haver um espaço em branco antes de cada comando.Reparem que foi utilizado joypad() sem nenhum parâmetro, caso este esteja omitido o padrão é 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 'so para nao ficar num loop frenetico e ocupar muito a cpu
joy = joypad() 'mesma coisa que no waitpadup
if joy.0 then ' cima
Print "cima"
endif
if joy.1 then ' baixo
Print "baixo"
endif
if joy.2 then ' esquerda
Print "esquerda"
endif
if joy.3 then ' direita
Print "direita"
endif
if joy.4 then ' b
Print "b"
endif
if joy.5 then ' c
Print "c"
endif
if joy.6 then ' a
Print "a"
endif
if joy.7 then ' start
Print "start"
endif
if joy.8 then ' z
Print "z"
endif
if joy.9 then ' y
Print "y"
endif
if joy.10 then ' x
Print "x"
endif
if joy.11 then 'mode 6 button
Print "mode 6 button"
endif
'voce tambem pode usar capturar mais de um envento ao mesmo tempo, por exemplo.
Desenvolvimento de jogos/Programação Megadrive 7
'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 invés de estrutura if-else por questões de desempenho, além de produzir uma melhorlegibilidade ao código. No caso do select utilize os valores decimais da tabela. Caso queiram capturar dois botoespor 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/Programação Megadrive 8
Movendo objetos pela tela
Utilizando o loop do exemplo acima que lê os comandos do controle. As unicas adições des comandos foram oaddsprite, propsprite, movesprite, e loadtiles. Irei comentar no codigo mesmo a função de cada coisa, caso alguemqueria criar um tópico explicando cada comando, fique a vontade. Explicando superficialmente sprites são aquelassequencias de imagens ([6]) que permite fazer a ilusao de um personagem em movimento. É possivel, e comumenteutilizado 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 SÃO
RESPECTIVAMENTE A QUANTIDADE DE TILE (CADA TILE É UM 'BLOCO' DE 8X8
PIXIELS) E
'O ENDEREÇO 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 ENDEREÇO DO
SPRITE
PROPSPRITE SPRITE,256,0 DESENHA O TILE' DE ENDEREÇO
SPRITE, INICIANDO NO ENDEREÇO DE MEMORIA 256, UTILIZANDO A PALETA DE
CORES NUMERO 0
X=280
Y=235
WHILE 1
SLEEP 2
MOVESPRITE SPRITE,X,Y 'MOVIMENTA O SPRITE PARA AS
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--
Desenvolvimento de jogos/Programação Megadrive 9
Y--
EXIT CASE
CASE 6:
X--
Y++
EXIT CASE
CASE 8:
X++
EXIT CASE
CASE 9:
X++
Y--
EXIT CASE
CASE 10:
X++
Y++
EXIT CASE
CASE ELSE:
EXIT SELECT
END SELECT
WEND
TILES: 'TILE CONVERTIDO, EU UTILIZEI
UMA FERRAMENTA PARA FAZER ESSA CONVERSAO
'E EMBORA CHATO NÃO É IMPOSSIVEL
DE SE FAZER NA MAO NAO
'É UMA ESPÉCIE 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 TÃO
DIFICIL, FAZER A PALETA DE CORES "NA MAO".
Desenvolvimento de jogos/Programação Megadrive 10
DATAINT $0000,$0000,$000E,$0004,$0008,$0000,$0000,$0000
DATAINT $0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000
Exibindo uma imagem no fundo da tela
Sei que a explicação não está muito didática mas estou tentando postar aqui conforme tenho tempo. Pela falta dedocumentação e exemplo em portugues, vamos a mais um exemplo pratico. Vou usar praticamente tudo do exemploanterior, espero que tenha ficado claro.Um pouco de teoria antes do exemplo. No mega drive existe 3 planos SCROLL_A, SCROLL_B, E WINDOW. Oplano SCROLL_B, possui a menor prioridade de todas, seguido pelo SCROLL_A, e por final WINDOW.Manipulando esses 3 planos é que damos a noção de 'profundidade' ao jogo, um elemento mais 'proximo', I.E, em umplano de maior prioridade, irá tapar o outro criando essa ilusao. O mais importante é os spirtes terao uma prioridademais alta, por isso nem me dei ao trabalho de atribuir os planos no exemplo a seguir. Existem mais comandos do queos que vou listar a baixo, recomendo ir buscar a documentação do BasiEgaXorz, vou explicar o basico só.Você pode usar os comandos:
SETTEXTPLANE <SCROLL_A/SCROLL_B/WINDOW>
Esse comando torna padrão para o ASCII, comandos tipo print e etc.
SETGFXPLANE <SCROLL_A/SCROLL_B/WINDOW>
Esse comando permite escolher qual será o plano padrão dos comandos de desenho, drawtile, drawtiles.
SETSCROLLPLANE <SCROLL_A/SCROLL_B>
Escolhe qual plano será 'rolado'.Esse não é um topico sobre scroll, estou explicando por que utilizei no codigo fonte e creio que ficará mais claroagora. Para adicionar as as imagens ao 'fundo', isto é imagens de um determinado plano. Existe varios comandoscomando drawtile, drawtiles, drawtilesovr, drawtilesinc, DrawTilesOvr, drawtilesinc2. Por hora eu não vou entrarem detalhes nesses varios comandos, vou explicar somente o drawtile (depois eu edito o topico com o resto doscomandos).
DRAWTILE <POSICAO DA MEMORIA>, <X DA TELA>, <Y DA TELA>
Desenha o determinado tile na tela, na posicão x,y. Com um for você pode preencher toda tela com a mesmaimagem, ou armazenar varios tiles que montem uma imagem maior e monta-la também com um for, sem maioresgrandes problemas.Dito isso, vamos ao exemplo prático. Boa parte do código foi retirado do exemplo acima então não terão dificuldadede 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 SÃO
RESPECTIVAMENTE A QUANTIDADE DE TILE (CADA TILE É UM 'BLOCO' DE 8X8
PIXIELS) E
'O ENDEREÇO 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/Programação Megadrive 11
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 ENDEREÇO DO
SPRITE
PROPSPRITE SPRITE,256,0 DESENHA O TILE' DE ENDEREÇO
SPRITE, INICIANDO NO ENDEREÇO 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
NÃO SE DEVE FAZER, A FUNÇÃO RANDOM GERA UM PROCESSAMENTO DESNECESSÁRIO.
DRAWTILE 257+RND(3),RND(40)+1,RND(63)+1 'E O PROCESSADOR DO
MEGA DRIVE NÃO 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
Desenvolvimento de jogos/Programação Megadrive 12
'ESSAS EXEÇÕES NO EXEMPLO. MAS NINGUEM DEVE TER
DIFICULDADE COM ISSO.
SCROLL2 DOWN, I 'MOVE O PLANO DE SCROLL,
SCROLL_B, PARA A POSICAO I...
SLEEP 1 'OBSERVAÇÃO 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 DIREÇÃO 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/Programação Megadrive 13
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 NÃO É IMPOSSIVEL
DE SE FAZER NA MAO NAO
'É UMA ESPÉCIE 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 $11122111 'NAVE, POSICAO 256
DATALONG $11322311
DATALONG $11322311
DATALONG $13244211
DATALONG $13244231
DATALONG $32433423
DATALONG $32433423
DATALONG $22222222
Desenvolvimento de jogos/Programação Megadrive 14
DATALONG $11111111 'ESTRELA GRANDE, POSICAO 257
DATALONG $11111111
DATALONG $11111111
DATALONG $11116111
DATALONG $11165611
DATALONG $11116111
DATALONG $11111111
DATALONG $11111111
DATALONG $11111111 'ESTRELA PEQUENA CLARA, POSICAO 258
DATALONG $11111111
DATALONG $11511111
DATALONG $11111111
DATALONG $11111111
DATALONG $11111111
DATALONG $11111111
DATALONG $11111111
DATALONG $11111111 'ESTRELA PEQUENA ESCURA, POSICAO 259
DATALONG $11111111
DATALONG $11111111
DATALONG $11111111
DATALONG $11111161
DATALONG $11111111
DATALONG $11111111
DATALONG $11111111
PALLETTEDATA: 'PALLET COM AS CORES DO TILE, EU
UTILIZEI UMA FERRAMENTA PARA DETECTAR AS CORES.
'MAS É POSSIVEL, E NEM TÃO
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 dúvida é um grande exemplo de jogo, devido sua simplicidade é um ótimo exercício para quem estácomeçando a programar. A título de informação foi o primeiro video game lucrativo da historia. Se não sabe do quese trata, esperto que essa imagem possa esclarecer. [7]Para começar vamos montar a estrutura do arquivo em BEX e ir progressivamente completando a cada tópico. Paracomeçar a explicação gostaria de falar que os você deve escolher uma posição de memoria em que os tiles serãoarmazenados. Contudo, da posição 0 até 255, já estão preenchidos com a tabela ascii [8]. Eu irei fazer uso dessescaracteres para desenhar a tela com o comando drawtile e passando o endereço deles ao comando.
Desenvolvimento de jogos/Programação Megadrive 15
Nosso ponto de "partida" será o exemplo abaixo, é importante que entenda o que está acontecendo no código paraprosseguir. Por isso está com muitos comentários. Além disso há várias substituições que podem ser feitas paradeixar o código mais otimizado, mas acredito que prejudicaria o entendimento, por isso vai assim mesmo. Quandoesse exemplo foi feito, o BasiEgaXorz não dava suporte número negativo, as últimas versões já o fazem. 'IGNORA AS OPÇÕES DE COMPILAÇÃO DA GUI, E COMPILA O JOGO PARA MEGA DRIVE (CARTUCHO)
OPTION CARTRIDGE
'OBRIGA EXPLICITAMENTE A DECLARAÇÃO DE VARIÁVEIS (BOAS PRÁTICA)
OPTION EXPLICIT
'DESABILITA A SENSIBILIDADE A CAIXA ALTA PARA VARIAVEIS, LABELS, FUNCÕES, ETC.
OPTION CASESENSE
'TÍTULO QUE SERÁ EXIBIDO NA JANELA DO SEU EMULADOR. (DEPOIS TITULO INSERIDO AUTOMATICAMENTE PELO BASIEGAXORZ)
OPTION TITLE, "PONG!"
'ATRIBUI OS COMANDOS DE DRAW PARA O PLANO SCROLL_B POR PADRÃO, E OS DE TEXTO AO PLANO SCROLL_A
SETGFXPLANE SCROLL_B
SETTEXTPLANE SCROLL_B
'EXECUTA A SUB QUE APRESENTARÁ A TELA DE APRESENTAÇÃO DO JOGO
APRESENTACAO
SLEEP 10
'EXECUTA A SUB QUE IRÁ DESENHAR A TELA DO PONG
DESENHA_TELA
'ALTERA O PADRÃO 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 REGIÃO DA MEMÓRIA É O INICIO DO SPRITE
PROPSPRITE JOGADOR,256, 0
PROPSPRITE CPU,256, 0
PROPSPRITE BOLA,7,2
Desenvolvimento de jogos/Programação Megadrive 16
'POSICIONA OS SPRITES NA TELA
MOVESPRITE JOGADOR, 136, 218
MOVESPRITE CPU, 432,218
MOVESPRITE BOLA, 142, 229
'LOOP DO JOGO
'VOU REMOVER TUDO DO LOOP
WHILE 1
SLEEP 1
MOVE_SPRITE JOGADOR
WEND
'FUNÇÃO QUE DESENHA A TELA (REDE, LATERAIS, JOGADORES)
DECLARE SUB DESENHA_TELA()
'DECLARA A VARIÁVEL DENTRO DA FUNÇÃO COMO LOCAL, A MEMÓRIA SERÁ LIBERADA APÓS O TERMINO DA FUNÇÃO (BOA PRÁTICA)
LOCAL I AS INTEGER
'ITERA UMA VEZ PARA CADA COLUNA
FOR I=1 TO 38
'AS POSIÇÕES DE MEMÓRIA ANTES DE 256 SÃO 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 POSIÇÃO 0,1 (O COMANDO LOCATE USA AS COORDENADAS Y,X E NÃO 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
'FUNÇÃO 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/Programação Megadrive 17
'EXECUTA UMA ESPERA ATÉ QUE O BOTÃO DE START SEJA PRESSIONADO. (USE O COMANDO SLEEP (BOA PRÁTICA))
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
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 $00000000 ' Tile #0
DATALONG $00022000
DATALONG $00233200
DATALONG $02211220
DATALONG $02311320
DATALONG $02311320
DATALONG $02311320
DATALONG $02311320
DATALONG $02311320 ' Tile #0
Desenvolvimento de jogos/Programação Megadrive 18
DATALONG $02311320
DATALONG $02311320
DATALONG $02311320
DATALONG $02311320
DATALONG $02311320
DATALONG $02311320
DATALONG $02311320
DATALONG $02311320 ' Tile #2
DATALONG $02311320
DATALONG $02311320
DATALONG $02311320
DATALONG $02311320
DATALONG $02311320
DATALONG $02311320
DATALONG $02311320
DATALONG $02311320 ' Tile #1
DATALONG $02311320
DATALONG $02311320
DATALONG $02311320
DATALONG $02211220
DATALONG $00233200
DATALONG $00022000
DATALONG $00000000
Fazendo a bola ricochetear pela tela
Basicamente não há nenhuma dificuldade com a linguagem aqui, mero algoritmico, qualquer programador com osconhecimentos de ifs-else consegue montar uma solução para esse problema. A minha não foi uma das melhores,nem a mais otimizada. Só um detalhe, o basiegaxorz não trabalha com numero negativo. Por isso a função não ficoumuito elegante. De todo modo, segue o fonte abaixo da função. Essa função está super simplória, vocês perceberão,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 DIREÇÃO 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 RÁPIDO, MAS NÃO TEM COMO FUGIR MUITO POIS NÃO TEMOS SUPORTE A VARIÁVEIS COM NÚMERO NEGATIVO.
'SE NÃO DAVA PARA FAZER ESSA FUNÇÃO 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 NÃO FOI PONTO
IF (X > 136) AND (X < 432) THEN
'NÃO FOI PONTO, VAMOS VERIFICAR SE CHEGOU EM ALGUMA PAREDE
IF (Y = 139) THEN
Desenvolvimento de jogos/Programação Megadrive 19
'CHEGOU NA PAREDE DE CIMA, VAMOS TROCAR A DIREÇÃO DA BOLA NO EIXO Y
SENTIDOY--
ELSE
'TESTANDO SE CHEGOU NA PAREDE DE BAIXO
IF (Y = 332) THEN
'CHEGOU, VAMOS MUDAR DE DIREÇÃO DA BOLA NO EIXO Y
SENTIDOY++
ENDIF
ENDIF
ELSE
'FOI PONTO
'COLOCAR A BOLA NA POSIÇÃO 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
Reparem que eu executei uma função PLACAR ela ainda "não existe" no seu código fonte então 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/Programação Megadrive 20
Checagem de colisão: Rebatendo a bola
Colisão é um assunto bem extenso. Tratar a colisão de qualquer modo é algo simples, contudo, de método eficientepode ser tornar uma tarefa bem complicada, principalmente levando em consideração as limitações do processadordo genesis.Mas o que posso falar rapidamente é que eu vou usar um método muito especifico, que não poderá ser aplicado apraticamente 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 acabeça, até descobri que o problema é no emulador). Caso queira testar seus codigos sugiro o emulador gens, é muitomais fiel ao funcionamento do video-game.A função COLLISION() utilizada no exemplo a baixo retorna o valor do SR, quando QUALQUER sprite colidir oseu valor será igual a 1, caso contrário igual a 0. Como nesse caso totalmente especifico não existe outra colisãopossível sem ser a bola com a raquete do pong. E em ambos os casos eu dei o mesmo tratamento, ou seja, se houvercolisão inverta o sentido no eixo X. Normalmente você nunca poderá usar esse método sozinho. Você jamais saberiausando ele se, um tiro acertou você ou se um tiro seu acertou um inimigo, ou se você bateu em um inimigo, se uminimigo atravessou o outro na tela, se um aliado passou por você, etc. A única vantagem desse método é: nãoenvolve nenhum processamento, o proprio hardware do mega drive faz isso.Outro detalhe, essa função normalmente não é usada por quem programa mega drive, procure ler mais sobre sprites egerar seus métodos ou usar algum conhecido. No proprio site do basiegaxorz nem existe a documentação dessafunção (também demorei um tempo para descobrir sua existência). Eu utilizo normalmente ela como gatilho para ummétodo mais interessante. Por exemplo, se houve alguma colisão "detectar quais, onde, etc.", assim evita chamadasde um método que consome mais recurso atoa.A unica alteração feita na função de mover a bolinha foi a inserção 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:
'QUANDO A BOLINHA ESTIVER VINDO PRA VOCÊ O SENTIDO X É 1, OU 0 QUANDO ESTIVER INDO NA DIREÇÃO 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 RÁPIDO, MAS NÃO TEM COMO FUGIR MUITO POIS NÃO TEMOS SUPORTE A VARIÁVEIS COM NÚMERO NEGATIVO.
'SE NÃO DAVA PARA FAZER ESSA FUNÇÃO 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 NÃO FOI PONTO
Desenvolvimento de jogos/Programação Megadrive 21
IF (X > 136) AND (X < 432) THEN
'NÃO FOI PONTO, VAMOS VERIFICAR SE CHEGOU EM ALGUMA PAREDE
IF (Y = 139) THEN
'CHEGOU NA PAREDE DE CIMA, VAMOS TROCAR A DIREÇÃO DA BOLA NO EIXO Y
SENTIDOY--
ELSE
'TESTANDO SE CHEGOU NA PAREDE DE BAIXO
IF (Y = 332) THEN
'CHEGOU, VAMOS MUDAR DE DIREÇÃO DA BOLA NO EIXO Y
SENTIDOY++
ENDIF
ENDIF
ELSE
'FOI PONTO
'COLOCAR A BOLA NA POSIÇÃO 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
Desenvolvimento de jogos/Programação Megadrive 22
ENDIF
END SUB
Marcando a pontuação
Duas funções aqui, a função "placar" que o exemplo acima está usando. E uma função para reiniciar o jogo, apos oplacar atingir 10.'NADA DE MAIS AQUI, SÓ VARIAVEIS GLOBAIS PARA MARCAR A PONTUAÇÃO DE CADA JOGADOR
GLOBAL PONTOS_JOGADOR AS INTEGER
GLOBAL PONTOS_CPU AS INTEGER
'FUNÇÃO QUE ATUALIZA O PLACAR
DECLARE SUB PLACAR(PONTO AS INTEGER)
'MUDA O PADRÃO 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 NÃO 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/Programação Megadrive 23
INK 0
'VOLTA A ESCRITA PADRÃO NO PLANO DE CIMA
SETTEXTPLANE SCROLL_A
END SUB
Função 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 função que desenha a tela, assim:
'EXECUTA A SUB QUE APRESENTARÁ A TELA DE APRESENTAÇÃO DO JOGO
APRESENTACAO
'LABEL QUE INDICA INICIO DO JOGO
INICIO
SLEEP 10
'EXECUTA A SUB QUE IRÁ DESENHAR A TELA DO PONG
DESENHA_TELA
Inteligência artificial básica: Jogador 1 versus CPU
IA horrivel, praticamente impossivel passar do CPU. Fiz mais para vocês terem uma noção do jogo funcionandomesmo. Com o movimento desse jeito da bolinha creio que é simplesmente impossivel passar algo pelo CPU. Mas aiestá.
'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/Programação Megadrive 24
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 faça um pongmelhor. 'IGNORA AS OPÇÕES DE COMPILAÇÃO DA GUI, E COMPILA O JOGO PARA MEGA DRIVE (CARTUCHO)
OPTION CARTRIDGE
'OBRIGA EXPLICITAMENTE A DECLARAÇÃO DE VARIÁVEIS (BOAS PRÁTICA)
OPTION EXPLICIT
'DESABILITA A SENSIBILIDADE A CAIXA ALTA PARA VARIAVEIS, LABELS, FUNCÕES, ETC.
OPTION CASESENSE
'TÍTULO QUE SERÁ EXIBIDO NA JANELA DO SEU EMULADOR. (DEPOIS TITULO INSERIDO AUTOMATICAMENTE PELO BASIEGAXORZ)
OPTION TITLE, "PONG!"
'ATRIBUI OS COMANDOS DE DRAW PARA O PLANO SCROLL_B POR PADRÃO, E OS DE TEXTO AO PLANO SCROLL_A
SETGFXPLANE SCROLL_B
SETTEXTPLANE SCROLL_B
'EXECUTA A SUB QUE APRESENTARÁ A TELA DE APRESENTAÇÃO 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 PADRÃO 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/Programação Megadrive 25
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 REGIÃO DA MEMÓRIA É 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
'FUNÇÃO QUE DESENHA A TELA (REDE, LATERAIS, JOGADORES)
DECLARE SUB DESENHA_TELA()
'DECLARA A VARIÁVEL DENTRO DA FUNÇÃO COMO LOCAL, A MEMÓRIA SERÁ LIBERADA APÓS O TERMINO DA FUNÇÃO (BOA PRÁTICA)
LOCAL I AS INTEGER
'ITERA UMA VEZ PARA CADA COLUNA
FOR I=1 TO 38
'AS POSIÇÕES DE MEMÓRIA ANTES DE 256 SÃO 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 POSIÇÃO 0,1 (O COMANDO LOCATE USA AS COORDENADAS Y,X E NÃO X,Y)
LOCATE 1,0
'MUDA A COR PARA VERDE
Desenvolvimento de jogos/Programação Megadrive 26
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
'FUNÇÃO 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 BOTÃO DE START SEJA PRESSIONADO. (USE O COMANDO SLEEP (BOA PRÁTICA))
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/Programação Megadrive 27
PRINT "=== PAUSE ==="
INK 0
SLEEP 10
WHILE JOYPAD() != 128 : SLEEP 2 : WEND
SLEEP 10
CLS
ENDIF
ENDIF
ENDIF
END SUB
'QUANDO A BOLINHA ESTIVER VINDO PRA VOCÊ O SENTIDO X É 1, OU 0 QUANDO ESTIVER INDO NA DIREÇÃO 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 RÁPIDO, MAS NÃO TEM COMO FUGIR MUITO POIS NÃO TEMOS SUPORTE A VARIÁVEIS COM NÚMERO NEGATIVO.
'SE NÃO DAVA PARA FAZER ESSA FUNÇÃO 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 NÃO FOI PONTO
IF (X > 136) AND (X < 432) THEN
'NÃO FOI PONTO, VAMOS VERIFICAR SE CHEGOU EM ALGUMA PAREDE
IF (Y = 139) THEN
'CHEGOU NA PAREDE DE CIMA, VAMOS TROCAR A DIREÇÃO DA BOLA NO EIXO Y
SENTIDOY--
ELSE
'TESTANDO SE CHEGOU NA PAREDE DE BAIXO
IF (Y = 332) THEN
'CHEGOU, VAMOS MUDAR DE DIREÇÃO DA BOLA NO EIXO Y
SENTIDOY++
ENDIF
ENDIF
ELSE
'FOI PONTO
'COLOCAR A BOLA NA POSIÇÃO 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/Programação Megadrive 28
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
'NADA DE MAIS AQUI, SÓ VARIAVEIS GLOBAIS PARA MARCAR A PONTUAÇÃO DE CADA JOGADOR
GLOBAL PONTOS_JOGADOR AS INTEGER
GLOBAL PONTOS_CPU AS INTEGER
'FUNÇÃO QUE ATUALIZA O PLACAR
DECLARE SUB PLACAR(PONTO AS INTEGER)
'MUDA O PADRÃO 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 NÃO 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/Programação Megadrive 29
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 PADRÃO NO PLANO DE CIMA
SETTEXTPLANE SCROLL_A
END SUB
'FUNÇÃO 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/Programação Megadrive 30
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
'TILE DA RAQUETE DOS JOGADORES
TILEDATA:
DATALONG $00000000 ' Tile #0
DATALONG $00022000
DATALONG $00233200
DATALONG $02211220
DATALONG $02311320
DATALONG $02311320
DATALONG $02311320
DATALONG $02311320
DATALONG $02311320 ' Tile #0
DATALONG $02311320
DATALONG $02311320
DATALONG $02311320
DATALONG $02311320
DATALONG $02311320
DATALONG $02311320
DATALONG $02311320
DATALONG $02311320 ' Tile #2
DATALONG $02311320
DATALONG $02311320
DATALONG $02311320
DATALONG $02311320
DATALONG $02311320
DATALONG $02311320
DATALONG $02311320
DATALONG $02311320 ' Tile #1
DATALONG $02311320
DATALONG $02311320
DATALONG $02311320
DATALONG $02211220
DATALONG $00233200
DATALONG $00022000
Desenvolvimento de jogos/Programação Megadrive 31
DATALONG $00000000
Intermediário
Avançado
Descrição das portas de I/O do Mega Drive
VDP
$C00000 (Porta de dados)
$C00004 (Porta de controle)
Leitura
* * * * * * VAZIO CHEIO
F SOVR C IMPAR VB HB PAL
VAZIO 1: FIFO de escrita vazio
0:
CHEIO 1: FIFO de escrita cheio
0:
F 1: Ocorreu interrupção vertical
SOVR 1: Ocorreu estouro de sprites. Muitos na mesma linha.
Mais de 17 no modo de 32 células.
Mais de 21 no modo de 40 células.
C 1: Ocorreu colisão entre dois pixels não nulos entre
dois sprites.
0:
IMPAR 1: Quadro ímpar no modo entrelaçado.
0: Quadro par no modo entrelaçado.
VB 1: Durante o "blanking" vertical
0:
HB 1: Durante o "blanking" horizontal
0:
DMA 1: Realizando DMA
0:
PAL 1: Modo PAL
0: Modo NTSC
Escrita 1: Enviar dados ao registrador
1 0 0 RS4 RS3 RS2 RS1 RS0
D7 D6 D5 D4 D3 D2 D1 D0
RS4 ~ RS0 : Número do registrador
D7 ~ D0 : Dados a enviar
•• As portas do VDP devem ser acessadas via "word" ou "long word", para correto funcionamento.
Desenvolvimento de jogos/Programação Megadrive 32
Escrita 2: Seleção de endereço
1ª Escrita
CD1 CD0 A13 A12 A11 A10 A9 A8
A7 A6 A5 A4 A3 A2 A1 A0
2ª Escrita
0 0 0 0 0 0 0 0
CD5 CD4 CD3 CD2 0 0 A15 A14
CD5 ~ CD0 : Código de indentificação
A15 ~ A0 : Endereço de destino
Modo de Acesso CD5 CD4 CD3 CD2 CD1 CD0
Escrita em VRAM 0 0 0 0 0 1
Escrita em CRAM 0 0 0 0 1 1
Escrita em VSRAM 0 0 0 1 0 1
Leitura da VRAM 0 0 0 0 0 0
Leitura da CRAM 0 0 1 0 0 0
Leitura da VSRAM 0 0 0 1 0 0
$C00008 (Contador horizontal/vertical)
Modo não entrelaçado
VC7 VC6 VC5 VC4 VC3 VC2 VC1 VC0
HC8 HC7 HC6 HC5 HC4 HC3 HC2 HC1
Modo entrelaçado
VC7 VC6 VC5 VC4 VC3 VC2 VC1 VC8
HC8 HC7 HC6 HC5 HC4 HC3 HC2 HC1
HC8 ~ HC1 : Posição horizontal
VC8 ~ VC0 : Posição vertical
Registradores
REG 0: Registrador de modo número 1
0 0 0 IE1 0 1 M3 0
IE1 1: Habilita interrupção horizontal (68000 nível 4)
0: Desabilita interrupção horizontal (REG #10)
M3 1: Parar o contador HV
0: Habilita o contador HV para leitura
REG 1: Registrador de modo número 2
0 DISP IE0 M1 M2 1 0 0
Desenvolvimento de jogos/Programação Megadrive 33
DISP 1: Habilita display
0: Desabilita display
IE0 1: Habilita interrupção vertical (68000 nível 6)
0: Desabilita interrupção vertical
M1 1: Habilita DMA
0: Desabilita DMA
M2 1: Modo 30 células na horizontal (modo PAL)
0: Modo 28 células na horizontal (Modo PAL, sempre 0 em modo NTSC)
REG 2: Endereço base do mapa do fundo A
0 0 SA15 SA14 SA13 0 0 0
Endereço da VRAM: $XXX0_0000_0000_0000
REG 3: Endereço base do mapa da janela
0 0 WD15 WD14 WD13 WD12 WD11 0
WD11 deve ser 0 no modo de 40 células horizontais
Endereço da VRAM: $XXXX_X000_0000_0000 (32 células horizontais)
Endereço da VRAM: $XXXX_0000_0000_0000 (40 células horizontais)
REG 4: Endereço base do mapa do fundo B
0 0 0 0 0 SB15 SB14 SB13
Endereço da VRAM: $XXX0_0000_0000_0000
REG 5: Endereço base da tabela de atributos dos sprites
0 AT15 AT14 AT13 AT12 AT11 AT10 AT9
WD9 deve ser 0 no modo de 40 células horizontais
Endereço da VRAM: $XXXX_XXX0_0000_0000 (32 células horizontais)
Endereço da VRAM: $XXXX_XX00_0000_0000 (40 células horizontais)
REG 7: Cor do fundo
0 0 CPT1 CPT0 COL3 COL2 COL1 COL0
CPT1 ~ CPT0 : Número da palheta
COL3 ~ COL0 : Código da cor
REG 10: Interrupção horizontal
BIT7 BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0
Conta o número da linha horizontal da tela sendo atualmente renderizado
REG 11: Registrador de modo número 3
Desenvolvimento de jogos/Programação Megadrive 34
0 0 0 0 IE2 VSCR HSCR LSCR
IE2 1: Habilita interrupção externa (68000 nível 2)
0: Desabilita interrupção externa
Modo de deslocamento horizontal
VSCR Função
0 Scroll completo
1 Scroll a cada duas células
Modo de deslocamento vertical
HSCR LSCR Função
0 0 Scroll completo
0 1 Inválido
1 0 Scroll célula a célula
1 1 Scroll linha a linha
REG 12: Registrador de modo número 4
RS0 0 0 0 S/TE LSM1 LSM0 RS1
RS0 0: Modo de 32 células horizontais
1: Modo de 40 células horizontais
RS1 0: Modo de 32 células horizontais
1: Modo de 40 células horizontais
* É recomendável setar o mesmo valor para RS0 e RS1.
S/TE 1: Habilita sombreamento e realce
0: Habilita sombreamento e realce
LSM1, LSM0: Modo de entrelaçamento
LSM1 LSM2 Função
0 0 Sem entrelaçamento
0 1 Entrelaçado
1 0 Inválido
1 1 Entrelaçado (Dupla resolução)
REG 13: Endereço da tabela de deslocamento horizontal
0 0 HS15 HS14 HS13 HS12 HS11 HS10
Endereço da VRAM: $XXXX_XX00_0000_0000
REG 15: Dados de auto incremento
A cada vez que a CPU acessa a memória da VDP do Mega Drive, a posição atual desta memória é incrementada.Este registrador define o tamanho do incremento.
Desenvolvimento de jogos/Programação 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 Função
0 0 32 células na vertical
0 1 64 células na vertical
1 0 Inválido
1 1 128 células na vertical
HSZ1 HSZ0 Função
0 0 32 células na horizontal
0 1 64 células na horizontal
1 0 Inválido
1 1 128 células na horizontal
REG 17: Posição 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 Posição horizontal em células, isto é de 8 em 8 pixels
REG 18: Posição 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 Posição vertical em células
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: Porção inferior do endereço de origem de DMA
SA8 SA7 SA6 SA5 SA4 SA3 SA2 SA1
REG 22: Porção central do endereço de origem de DMA
Desenvolvimento de jogos/Programação Megadrive 36
SA16 SA15 SA14 SA13 SA12 SA11 SA10 SA9
REG 23: Porção superior do endereço de origem de DMA
DMD1 DMD0 SA22 SA21 SA20 SA19 SA18 SA17
SA22 ~ SA1 : Endereço de origem de DMA
DMD1, DMD0 : Modo de DMA
DMD1 DMD0 Função
0 SA23 Memória para vídeo
1 0 Preenche VRAM
1 1 Vídeo para vídeo
Exemplo de utilização 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=interrupção externa
b=scroll horiz. cd=scroll vert. */
*pw = 0x8c81; /* reg 12 - células horiz + sombreamento/realce +
modo entrelaçamento (40 células,
sem sombreamento, sem entrelaçamento)*/
*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 - posição horizontal da janela */
*pw = 0x92ff; /* reg 18 - posição vertical da janela */
};
Desenvolvimento de jogos/Programação Megadrive 37
Programação assembly 68k
Documentação Assembly
A extensa documentação do assembly do 68k pode ser encontrada no Devega [9].
Cabeçalho da ROM
O cabeçalho da ROM para Mega Drive consiste de duas seções, cada uma de 256 bytes. A primeira é "exigida" peloprocessador, e indicam o início da pilha, o endereço da rotina principal e os endereços das rotinas de exceções(traps) e interrupções. Já a segunda seção é uma padronização realizada pela SEGA para identificação do cartucho(direitos autorais, nome do produto, etc.) e informações sobre utilização de recursos do hardware (mapeamento dememória, periféricos, etc.).
Os elementos mais usados do Vetor de Exceções (primeiros 256 bytes)
Item Endereço Descrição
1 0x000000 Endereço do início da pilha (geralmente próximo ao fim da memória RAM)
2 0x000004 Endereço da rotina principal (valor inicial do PC, também para quando resetado)
26 0x000068 Interrupção de nível 2: no Mega Drive, Externa.
28 0x000070 Interrupção de nível 4: no Mega Drive, Retraço Horizontal.
30 0x000078 Interrupção de nível 6: no Mega Drive, Retraço Vertical.
O conteúdo de cada elemento do Vetor de Exceções é o endereço absoluto (em relação ao primeiro byte do arquivobinário) da respectiva rotina de tratamento da exceção. Cada elemento consiste de 4 bytes.O costume é, quando for desejado não tratar certas exceções, elas reiniciem o software, ou seja, apontem para ocomeço do programa. Vale destacar que as interrupções de retraço devem ser tratadas, nem que seja não fazer nada,já que são efetivamente geradas a tempo constante.As demais exceções/interrupções não citadas podem ser encontradas no Apêndice B do MOTOROLA M68000FAMILY Programmer's Reference Manual disponível no Devega [9].
Referências[1] http:/ / www. gnu. org/ software/ binutils/[2] http:/ / devster. monkeeh. com/ sega/ basiegaxorz/[3] http:/ / www. chez. com/ kaneda/ index. php[4] http:/ / www. classicgaming. com/ epr/ genesis. htm[5] http:/ / home. hiwaay. net/ ~eubanks/[6] http:/ / gamesprite. files. wordpress. com/ 2008/ 01/ iris. gif[7] http:/ / pomoti. com/ wp-content/ uploads/ 2008/ 10/ pong. jpg[8] http:/ / www. abusar. org/ images/ ascii. gif[9] http:/ / www. emulationzone. org/ projects/ metalix/ 68kmanuals. htm
Fontes e Editores da Página 38
Fontes e Editores da PáginaDesenvolvimento de jogos/Programação Megadrive Fonte: http://pt.wikibooks.org/w/index.php?oldid=226633 Contribuidores: Defender, Haroldoop, Helder.wiki, Jorge Morais, MarcosAntônio Nunes de Moura, Rodolforg, Wutsje, 40 edições anónimas
LicençaCreative Commons Attribution-Share Alike 3.0 Unported//creativecommons.org/licenses/by-sa/3.0/