You've already forked pokecrystal-board
mirror of
https://gitlab.com/xCrystal/pokecrystal-board.git
synced 2025-04-09 05:44:44 -07:00
Split out joypad
This commit is contained in:
@@ -3417,6 +3417,11 @@ BATTLETYPE_SUICUNE EQU $0c
|
|||||||
|
|
||||||
|
|
||||||
; joypad
|
; joypad
|
||||||
|
BUTTONS EQU %00010000
|
||||||
|
D_PAD EQU %00100000
|
||||||
|
|
||||||
|
AUTO_INPUT EQU $ff
|
||||||
|
|
||||||
NO_INPUT EQU %00000000
|
NO_INPUT EQU %00000000
|
||||||
BUTTON_A EQU %00000001
|
BUTTON_A EQU %00000001
|
||||||
BUTTON_B EQU %00000010
|
BUTTON_B EQU %00000010
|
||||||
|
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
|
jp $06ef
|
||||||
|
|
||||||
SECTION "joypad",HOME[$60] ; joypad interrupt
|
SECTION "joypad",HOME[$60] ; joypad interrupt
|
||||||
jp $092e
|
jp JoypadInt
|
||||||
|
|
||||||
SECTION "romheader",HOME[$100]
|
SECTION "romheader",HOME[$100]
|
||||||
Start:
|
Start:
|
||||||
@@ -425,252 +425,11 @@ SetClock: ; 691
|
|||||||
ret
|
ret
|
||||||
; 6c4
|
; 6c4
|
||||||
|
|
||||||
INCBIN "baserom.gbc",$6c4,$935 - $6c4
|
INCBIN "baserom.gbc",$6c4,$92e - $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
|
|
||||||
|
|
||||||
|
|
||||||
GetJoypadPublic: ; 984
|
INCLUDE "joypad.asm"
|
||||||
; update mirror joypad input from $ffa4 (real input)
|
|
||||||
|
|
||||||
; $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
|
INCBIN "baserom.gbc",$a1b,$b40 - $a1b
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user