mirror of
https://gitlab.com/xCrystal/pokecrystal-board.git
synced 2024-11-16 11:27:33 -08:00
Split out joypad
This commit is contained in:
parent
9102b9a498
commit
da406973c5
@ -3417,15 +3417,20 @@ BATTLETYPE_SUICUNE EQU $0c
|
||||
|
||||
|
||||
; joypad
|
||||
NO_INPUT EQU %00000000
|
||||
BUTTON_A EQU %00000001
|
||||
BUTTON_B EQU %00000010
|
||||
SELECT EQU %00000100
|
||||
START EQU %00001000
|
||||
D_RIGHT EQU %00010000
|
||||
D_LEFT EQU %00100000
|
||||
D_UP EQU %01000000
|
||||
D_DOWN EQU %10000000
|
||||
BUTTONS EQU %00010000
|
||||
D_PAD EQU %00100000
|
||||
|
||||
AUTO_INPUT EQU $ff
|
||||
|
||||
NO_INPUT EQU %00000000
|
||||
BUTTON_A EQU %00000001
|
||||
BUTTON_B EQU %00000010
|
||||
SELECT EQU %00000100
|
||||
START EQU %00001000
|
||||
D_RIGHT EQU %00010000
|
||||
D_LEFT EQU %00100000
|
||||
D_UP EQU %01000000
|
||||
D_DOWN EQU %10000000
|
||||
|
||||
; mbc
|
||||
NUM_SRAM_BANKS EQU 4
|
||||
|
275
joypad.asm
Normal file
275
joypad.asm
Normal file
@ -0,0 +1,275 @@
|
||||
JoypadInt: ; 92e
|
||||
; Replaced by Joypad, called from VBlank instead of the useless
|
||||
; joypad interrupt.
|
||||
|
||||
; This is a placeholder in case the interrupt is somehow enabled.
|
||||
reti
|
||||
; 92f
|
||||
|
||||
ClearJoypadPublic: ; 92f
|
||||
xor a
|
||||
; Pressed this frame (delta)
|
||||
ld [$ffa7], a
|
||||
; Currently pressed
|
||||
ld [$ffa8], a
|
||||
ret
|
||||
; 935
|
||||
|
||||
Joypad: ; 935
|
||||
; Read the joypad register and translate it to something more
|
||||
; workable for use in-game. There are 8 buttons, so we can use
|
||||
; one byte to contain all player input.
|
||||
|
||||
; Updates:
|
||||
|
||||
; $ffa2: released this frame (delta)
|
||||
; $ffa3: pressed this frame (delta)
|
||||
; $ffa4: currently pressed
|
||||
; $ffa5: pressed so far
|
||||
|
||||
; Any of these three bits can be used to disable input.
|
||||
ld a, [$cfbe]
|
||||
and %11010000
|
||||
ret nz
|
||||
|
||||
; If we're saving, input is disabled.
|
||||
ld a, [$c2cd]
|
||||
and a
|
||||
ret nz
|
||||
|
||||
; We can only get four inputs at a time.
|
||||
; We take d-pad first for no particular reason.
|
||||
ld a, D_PAD
|
||||
ld [$ff00], a
|
||||
; Read twice to give the request time to take.
|
||||
ld a, [$ff00]
|
||||
ld a, [$ff00]
|
||||
|
||||
; The Joypad register output is in the lo nybble (inversed).
|
||||
; We make the hi nybble of our new container d-pad input.
|
||||
cpl
|
||||
and $f
|
||||
swap a
|
||||
|
||||
; We'll keep this in b for now.
|
||||
ld b, a
|
||||
|
||||
; Buttons make 8 total inputs (A, B, Select, Start).
|
||||
; We can fit this into one byte.
|
||||
ld a, BUTTONS
|
||||
ld [$ff00], a
|
||||
; Wait for input to stabilize.
|
||||
ld a, [$ff00]
|
||||
ld a, [$ff00]
|
||||
ld a, [$ff00]
|
||||
ld a, [$ff00]
|
||||
ld a, [$ff00]
|
||||
ld a, [$ff00]
|
||||
; Buttons take the lo nybble.
|
||||
cpl
|
||||
and $f
|
||||
or b
|
||||
ld b, a
|
||||
|
||||
; Reset the joypad register since we're done with it.
|
||||
ld a, $30
|
||||
ld [$ff00], a
|
||||
|
||||
; To get the delta we xor the last frame's input with the new one.
|
||||
ld a, [$ffa4] ; last frame
|
||||
ld e, a
|
||||
xor b
|
||||
ld d, a
|
||||
; Released this frame:
|
||||
and e
|
||||
ld [$ffa2], a
|
||||
; Pressed this frame:
|
||||
ld a, d
|
||||
and b
|
||||
ld [$ffa3], a
|
||||
|
||||
; Add any new presses to the list of collective presses:
|
||||
ld c, a
|
||||
ld a, [$ffa5]
|
||||
or c
|
||||
ld [$ffa5], a
|
||||
|
||||
; Currently pressed:
|
||||
ld a, b
|
||||
ld [$ffa4], a
|
||||
|
||||
; Now that we have the input, we can do stuff with it.
|
||||
|
||||
; For example, soft reset:
|
||||
and BUTTON_A | BUTTON_B | SELECT | START
|
||||
cp BUTTON_A | BUTTON_B | SELECT | START
|
||||
jp z, $0150 ; reset
|
||||
|
||||
ret
|
||||
; 984
|
||||
|
||||
|
||||
GetJoypadPublic: ; 984
|
||||
; Update mirror joypad input from $ffa4 (real input)
|
||||
|
||||
; $ffa6: released this frame (delta)
|
||||
; $ffa7: pressed this frame (delta)
|
||||
; $ffa8: currently pressed
|
||||
|
||||
; bit 0 A
|
||||
; 1 B
|
||||
; 2 SELECT
|
||||
; 3 START
|
||||
; 4 RIGHT
|
||||
; 5 LEFT
|
||||
; 6 UP
|
||||
; 7 DOWN
|
||||
|
||||
push af
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
|
||||
; The player input can be automated using an input stream.
|
||||
; See more below.
|
||||
ld a, [InputType]
|
||||
cp a, AUTO_INPUT
|
||||
jr z, .auto
|
||||
|
||||
; To get deltas, take this and last frame's input.
|
||||
ld a, [$ffa4] ; real input
|
||||
ld b, a
|
||||
ld a, [$ffa8] ; last frame mirror
|
||||
ld e, a
|
||||
|
||||
; Released this frame:
|
||||
xor b
|
||||
ld d, a
|
||||
and e
|
||||
ld [$ffa6], a
|
||||
|
||||
; Pressed this frame:
|
||||
ld a, d
|
||||
and b
|
||||
ld [$ffa7], a
|
||||
|
||||
; It looks like the collective presses got commented out here.
|
||||
ld c, a
|
||||
|
||||
; Currently pressed:
|
||||
ld a, b
|
||||
ld [$ffa8], a ; frame input
|
||||
|
||||
.quit
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
pop af
|
||||
ret
|
||||
|
||||
.auto
|
||||
; Use a predetermined input stream (used in the catching tutorial).
|
||||
|
||||
; Stream format: [input][duration]
|
||||
; A value of $ff will immediately end the stream.
|
||||
|
||||
; Read from the input stream.
|
||||
ld a, [$ff9d]
|
||||
push af
|
||||
ld a, [AutoInputBank]
|
||||
rst Bankswitch
|
||||
|
||||
ld hl, AutoInputAddress
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
|
||||
; We only update when the input duration has expired.
|
||||
ld a, [AutoInputLength]
|
||||
and a
|
||||
jr z, .updateauto
|
||||
|
||||
; Until then, don't change anything.
|
||||
dec a
|
||||
ld [AutoInputLength], a
|
||||
pop af
|
||||
rst Bankswitch
|
||||
jr .quit
|
||||
|
||||
|
||||
.updateauto
|
||||
; An input of $ff will end the stream.
|
||||
ld a, [hli]
|
||||
cp a, $ff
|
||||
jr z, .stopauto
|
||||
ld b, a
|
||||
|
||||
; A duration of $ff will end the stream indefinitely.
|
||||
ld a, [hli]
|
||||
ld [AutoInputLength], a
|
||||
cp a, $ff
|
||||
jr nz, .next
|
||||
|
||||
; The current input is overwritten.
|
||||
dec hl
|
||||
dec hl
|
||||
ld b, NO_INPUT
|
||||
jr .finishauto
|
||||
|
||||
.next
|
||||
; On to the next input...
|
||||
ld a, l
|
||||
ld [AutoInputAddress], a
|
||||
ld a, h
|
||||
ld [AutoInputAddress+1], a
|
||||
jr .finishauto
|
||||
|
||||
.stopauto
|
||||
call StopAutoInput
|
||||
ld b, NO_INPUT
|
||||
|
||||
.finishauto
|
||||
pop af
|
||||
rst Bankswitch
|
||||
ld a, b
|
||||
ld [$ffa7], a ; pressed
|
||||
ld [$ffa8], a ; input
|
||||
jr .quit
|
||||
; 9ee
|
||||
|
||||
|
||||
StartAutoInput: ; 9ee
|
||||
; Start reading automated input stream at a:hl.
|
||||
|
||||
ld [AutoInputBank], a
|
||||
ld a, l
|
||||
ld [AutoInputAddress], a
|
||||
ld a, h
|
||||
ld [AutoInputAddress+1], a
|
||||
; Start reading the stream immediately.
|
||||
xor a
|
||||
ld [AutoInputLength], a
|
||||
; Reset input mirrors.
|
||||
xor a
|
||||
ld [$ffa7], a ; pressed this frame
|
||||
ld [$ffa6], a ; released this frame
|
||||
ld [$ffa8], a ; currently pressed
|
||||
|
||||
ld a, AUTO_INPUT
|
||||
ld [InputType], a
|
||||
ret
|
||||
; a0a
|
||||
|
||||
|
||||
StopAutoInput: ; a0a
|
||||
; Clear variables related to automated input.
|
||||
xor a
|
||||
ld [AutoInputBank], a
|
||||
ld [AutoInputAddress], a
|
||||
ld [AutoInputAddress+1], a
|
||||
ld [AutoInputLength], a
|
||||
; Back to normal input.
|
||||
ld [InputType], a
|
||||
ret
|
||||
; a1b
|
||||
|
247
main.asm
247
main.asm
@ -47,7 +47,7 @@ SECTION "serial",HOME[$58] ; serial interrupt
|
||||
jp $06ef
|
||||
|
||||
SECTION "joypad",HOME[$60] ; joypad interrupt
|
||||
jp $092e
|
||||
jp JoypadInt
|
||||
|
||||
SECTION "romheader",HOME[$100]
|
||||
Start:
|
||||
@ -425,252 +425,11 @@ SetClock: ; 691
|
||||
ret
|
||||
; 6c4
|
||||
|
||||
INCBIN "baserom.gbc",$6c4,$935 - $6c4
|
||||
|
||||
Joypad: ; 935
|
||||
; update joypad state
|
||||
; $ffa2: released
|
||||
; $ffa3: pressed
|
||||
; $ffa4: input
|
||||
; $ffa5: total pressed
|
||||
|
||||
;
|
||||
ld a, [$cfbe]
|
||||
and $d0
|
||||
ret nz
|
||||
|
||||
; pause game update?
|
||||
ld a, [$c2cd]
|
||||
and a
|
||||
ret nz
|
||||
|
||||
; d-pad
|
||||
ld a, $20
|
||||
ld [$ff00], a
|
||||
ld a, [$ff00]
|
||||
ld a, [$ff00]
|
||||
; hi nybble
|
||||
cpl
|
||||
and $f
|
||||
swap a
|
||||
ld b, a
|
||||
|
||||
; buttons
|
||||
ld a, $10
|
||||
ld [$ff00], a
|
||||
; wait to stabilize
|
||||
ld a, [$ff00]
|
||||
ld a, [$ff00]
|
||||
ld a, [$ff00]
|
||||
ld a, [$ff00]
|
||||
ld a, [$ff00]
|
||||
ld a, [$ff00]
|
||||
; lo nybble
|
||||
cpl
|
||||
and $f
|
||||
or b
|
||||
ld b, a
|
||||
|
||||
; reset joypad
|
||||
ld a, $30
|
||||
ld [$ff00], a
|
||||
|
||||
; get change in input
|
||||
ld a, [$ffa4] ; last frame's input
|
||||
ld e, a
|
||||
xor b ; current frame input
|
||||
ld d, a
|
||||
; released
|
||||
and e
|
||||
ld [$ffa2], a
|
||||
; pressed
|
||||
ld a, d
|
||||
and b
|
||||
ld [$ffa3], a
|
||||
|
||||
; total pressed
|
||||
ld c, a
|
||||
ld a, [$ffa5]
|
||||
or c
|
||||
ld [$ffa5], a
|
||||
|
||||
; original input
|
||||
ld a, b
|
||||
ld [$ffa4], a
|
||||
|
||||
; A+B+SELECT+START
|
||||
and $f
|
||||
cp $f
|
||||
jp z, $0150 ; reset
|
||||
|
||||
ret
|
||||
; 984
|
||||
INCBIN "baserom.gbc",$6c4,$92e - $6c4
|
||||
|
||||
|
||||
GetJoypadPublic: ; 984
|
||||
; update mirror joypad input from $ffa4 (real input)
|
||||
INCLUDE "joypad.asm"
|
||||
|
||||
; $ffa6: released
|
||||
; $ffa7: pressed
|
||||
; $ffa8: input
|
||||
|
||||
; bit 0 A
|
||||
; 1 B
|
||||
; 2 SELECT
|
||||
; 3 START
|
||||
; 4 RIGHT
|
||||
; 5 LEFT
|
||||
; 6 UP
|
||||
; 7 DOWN
|
||||
|
||||
push af
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
|
||||
; automated input?
|
||||
ld a, [InputType]
|
||||
cp a, $ff ; INPUT_AUTO
|
||||
jr z, .auto
|
||||
|
||||
; get input
|
||||
ld a, [$ffa4] ; real input
|
||||
ld b, a
|
||||
ld a, [$ffa8] ; last frame mirror
|
||||
ld e, a
|
||||
|
||||
; released
|
||||
xor b
|
||||
ld d, a
|
||||
and e
|
||||
ld [$ffa6], a
|
||||
|
||||
; pressed
|
||||
ld a, d
|
||||
and b
|
||||
ld [$ffa7], a
|
||||
|
||||
; leftover from pasted code
|
||||
ld c, a
|
||||
|
||||
;
|
||||
ld a, b
|
||||
ld [$ffa8], a ; frame input
|
||||
.quit
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
pop af
|
||||
ret
|
||||
|
||||
.auto
|
||||
; use predetermined input feed (used in catch tutorial)
|
||||
; struct: [input][duration]
|
||||
|
||||
; save bank
|
||||
ld a, [$ff9d]
|
||||
push af
|
||||
;
|
||||
ld a, [AutoInputBank]
|
||||
rst Bankswitch
|
||||
;
|
||||
ld hl, AutoInputAddress ; AutoInputAddress-9
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
|
||||
; update when frame count hits 0
|
||||
ld a, [AutoInputLength]
|
||||
and a
|
||||
jr z, .updateauto
|
||||
|
||||
; until then, do nothing
|
||||
dec a
|
||||
ld [AutoInputLength], a
|
||||
; restore bank
|
||||
pop af
|
||||
rst Bankswitch
|
||||
; we're done
|
||||
jr .quit
|
||||
|
||||
.updateauto
|
||||
; get input
|
||||
ld a, [hli]
|
||||
; stop?
|
||||
cp a, $ff
|
||||
jr z, .stopinput
|
||||
ld b, a
|
||||
|
||||
; duration
|
||||
ld a, [hli]
|
||||
ld [AutoInputLength], a
|
||||
; duration $ff = end at input
|
||||
cp a, $ff
|
||||
jr nz, .next
|
||||
|
||||
; no input
|
||||
dec hl
|
||||
dec hl
|
||||
ld b, $00 ; no input
|
||||
jr .finishauto
|
||||
|
||||
.next
|
||||
; output recorded
|
||||
ld a, l
|
||||
ld [AutoInputAddress], a
|
||||
ld a, h
|
||||
ld [AutoInputAddress+1], a
|
||||
jr .finishauto
|
||||
|
||||
.stopinput
|
||||
call StopAutoInput
|
||||
ld b, $00 ; no input
|
||||
|
||||
.finishauto
|
||||
; restore bank
|
||||
pop af
|
||||
rst Bankswitch
|
||||
; update mirrors
|
||||
ld a, b
|
||||
ld [$ffa7], a ; pressed
|
||||
ld [$ffa8], a ; input
|
||||
jr .quit
|
||||
; 9ee
|
||||
|
||||
StartAutoInput: ; 9ee
|
||||
; start auto input stream at a:hl
|
||||
; bank
|
||||
ld [AutoInputBank], a
|
||||
; address
|
||||
ld a, l
|
||||
ld [AutoInputAddress], a
|
||||
ld a, h
|
||||
ld [AutoInputAddress+1], a
|
||||
; don't wait to update
|
||||
xor a
|
||||
ld [AutoInputLength], a
|
||||
; clear input mirrors
|
||||
xor a
|
||||
ld [$ffa7], a ; pressed
|
||||
ld [$ffa6], a ; released
|
||||
ld [$ffa8], a ; input
|
||||
; start reading input stream instead of player input
|
||||
ld a, $ff ; INPUT_AUTO
|
||||
ld [InputType], a
|
||||
ret
|
||||
; a0a
|
||||
|
||||
StopAutoInput: ; a0a
|
||||
; clear autoinput ram
|
||||
xor a
|
||||
ld [AutoInputBank], a
|
||||
ld [AutoInputAddress], a
|
||||
ld [AutoInputAddress+1], a
|
||||
ld [AutoInputLength], a
|
||||
; normal input
|
||||
ld [InputType], a
|
||||
ret
|
||||
; a1b
|
||||
|
||||
INCBIN "baserom.gbc",$a1b,$b40 - $a1b
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user