sexta-feira, 20 de janeiro de 2012

Jogos da Konami com Nunchuck

Estive vendo que alguns jogos da Konami são bem parecidos na inicialização e na leitura dos joysticks. Então o procedimento para modifica-los para usar o Nunchuck (ou outro joystick) é bem parecido.

Basicamente, os jogos que vi iniciam a área e variáveis e depois entram num loop infinito.


...
407C EI
407D JR 0407DH
...


As rotinas de leitura de joystick têm como entrada o registrador E contendo bit 6 (ABSEL) em 1 ou em 0 dependendo da porta de joystick que se quer ler e retornam o estado do registrador 14 do PSG com os dois bits mais significativos em zero.


...
46C5 LD A,00Fh
46C7 CALL WRTPSG
46CA LD A,0Eh
46CC DI
46CD CALL RDPSG
46D0 EI
46D1 CPL
46D2 AND 03Fh
...


Então para usar o nunchuck é necessário alterar esses dois pontos do codigo. O primeiro para colocar a rotina de inicialização do nunchuck e o segundo para fazer a leitura, retornando o estado do nunchuck mapeado para os pinos do joystick.

Um exemplo, para Road Fighter, São tres bytes que podem ser modificados para:


org 0407ch
JP INITNUNS


E rotina de leitura pode ser modificada assim

org 046c3h
CALL READNUN
JR 046d2h


Daí a rotina que inicializa os nunchucks pode inclusive sinalizar num flag se conseguiu identificar a presença do nunchuck, de forma que a rotina de leitura possa reverter para o joystick original, caso o nunchuck não responda no barramento I2C.


org 09000h
;
;
;
INITNUNS:
XOR A ; Zera A e seleciona J2C port A (CY =0)
LD (NUNFLG), A ; armazena zero em NUNFLG
CALL INITNUN ; inicia nunchuck e seta bit 1 de NUNFLG se nunch 1 ok.
JR C,INNUN1 ; Se nunchuck na porta 1 não respondeu tenta o outro
SET 1,A ; Se respondeu, marca o flag
INNUN1:
SCF ; seleciona J2C port B
CALL INITNUN ; inicia nunchuck e seta bit 1 de NUNFLG se nunch 1 ok.
JR C,INNUN2 ; Se nunchuck na porta 2 não respondeu entra no loop
SET 2,A ; Se respondeu, marca o flag

INNUN2:
EI
LOOP: JR LOOP ; loop infinito do jogo


E a rotina de leitura fica assim...

;
;
READNUN: ; Registro E como entrada. Bit 6 seleciona se porta A ou B
BIT 6,E ; Z= Porta A, NZ=Porta B
JR NZ,LEPORTB

LEPORTA: ; Processa joystick A
LD A,(NUNFLG)
BIT 1,A ; testa se há nunchuck na porta A
JR Z,READSTICK ; Lê joystick normalmente se nao houver nunchuck
AND A ; seleciona J2C port A (CY =0)
JR LEITURA ; Le e interpreta
;
LEPORTB: ; Processa joystick A
LD A,(NUNFLG)
BIT 2,A ; testa se há nunchuck na porta A
JR Z,READSTICK ; Lê joystick normalmente se nao houver nunchuck
SCF ; seleciona J2C port B (CY =1)
;
LEITURA:
CALL LENUNCH ; Lê nunchuck
CALL INTERPRETA ; Interpreta leitura (retorna 00BARLDU em A)
EI
RET


A rotina de interpretação mapeia os sensores do nunchuck da seguinte forma:

Eixo X > limiar positivo = Direita acionada
Eixo X < limiar negativo = Esquerda acionada
Eixo Y > limiar positivo = Acima acionado
Eixo Y < limiar negativo = Abaixo acionado

Acelerometro X > limiar positivo = Direita acionada
Acelerometro X < limiar negativo = Esquerda acionada
Acelerometro Y > limiar positivo = Acima acionado
Acelerometro Y < limiar negativo = Abaixo acionado

Botao C acionado = Trigger B acionado
Botao Z acionado = Trigger A acionado.

Nenhum comentário: