shithub: pokecrystal

ref: 11fea1945586f9791ed8621699900bb63ffd6be4
dir: /engine/joypad.asm/

View raw version
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 [hJoyPressed], a
; Currently pressed
	ld [hJoyDown], 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:

; hJoypadReleased: released this frame (delta)
; hJoypadPressed: pressed this frame (delta)
; hJoypadDown: currently pressed
; hJoypadSum: 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 [rJOYP], a
; Read twice to give the request time to take.
	ld a, [rJOYP]
	ld a, [rJOYP]
	
; 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 [rJOYP], a
; Wait for input to stabilize.
	ld a, [rJOYP]
	ld a, [rJOYP]
	ld a, [rJOYP]
	ld a, [rJOYP]
	ld a, [rJOYP]
	ld a, [rJOYP]
; 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 [rJOYP], a
	
; To get the delta we xor the last frame's input with the new one.
	ld a, [hJoypadDown] ; last frame
	ld e, a
	xor b
	ld d, a
; Released this frame:
	and e
	ld [hJoypadReleased], a
; Pressed this frame:
	ld a, d
	and b
	ld [hJoypadPressed], a
	
; Add any new presses to the list of collective presses:
	ld c, a
	ld a, [hJoypadSum]
	or c
	ld [hJoypadSum], a
	
; Currently pressed:
	ld a, b
	ld [hJoypadDown], 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, Reset
	
	ret
; 984


GetJoypadPublic: ; 984
; Update mirror joypad input from hJoypadDown (real input)

; hJoyReleased: released this frame (delta)
; hJoyPressed: pressed this frame (delta)
; hJoyDown: 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, [hJoypadDown] ; real input
	ld b, a
	ld a, [hJoyDown] ; last frame mirror
	ld e, a
	
; Released this frame:
	xor b
	ld d, a
	and e
	ld [hJoyReleased], a
	
; Pressed this frame:
	ld a, d
	and b
	ld [hJoyPressed], a
	
; It looks like the collective presses got commented out here.
	ld c, a
	
; Currently pressed:
	ld a, b
	ld [hJoyDown], 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, [hROMBank]
	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 [hJoyPressed], a ; pressed
	ld [hJoyDown], 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 [hJoyPressed], a ; pressed this frame
	ld [hJoyReleased], a ; released this frame
	ld [hJoyDown], 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


Functiona1b: ; a1b

	call DelayFrame

	push bc
	call Functiona57
	pop bc

	ld a, [hJoyDown]
	cp D_UP | SELECT | BUTTON_B
	jr z, .asm_a34

	ld a, [$ffa9]
	and START | BUTTON_A
	jr nz, .asm_a34

	dec c
	jr nz, Functiona1b

	and a
	ret

.asm_a34
	scf
	ret
; a36


Functiona36: ; a36
	call DelayFrame
	call GetJoypadPublic
	ld a, [hJoyPressed]
	and BUTTON_A | BUTTON_B
	ret nz
	call RTC
	jr Functiona36
; a46

Functiona46: ; a46
	ld a, [hOAMUpdate]
	push af
	ld a, 1
	ld [hOAMUpdate], a
	call WaitBGMap
	call Functiona36
	pop af
	ld [hOAMUpdate], a
	ret
; a57

Functiona57: ; a57
	call GetJoypadPublic
	ld a, [$ffaa]
	and a
	ld a, [hJoyPressed]
	jr z, .asm_a63
	ld a, [hJoyDown]
.asm_a63
	ld [$ffa9], a
	ld a, [hJoyPressed]
	and a
	jr z, .asm_a70
	ld a, 15
	ld [TextDelayFrames], a
	ret

.asm_a70
	ld a, [TextDelayFrames]
	and a
	jr z, .asm_a7a
	xor a
	ld [$ffa9], a
	ret

.asm_a7a
	ld a, 5
	ld [TextDelayFrames], a
	ret
; a80

Functiona80: ; a80
	ld a, [$ffaf]
	push af
	ld a, [$ffb0]
	push af
	xor a
	ld [$ffaf], a
	ld a, $6
	ld [$ffb0], a
.asm_a8d
	push hl
	ld hl, $c606
	call Functionb06
	pop hl
	call Functiona57
	ld a, [$ffa9]
	and $3
	jr z, .asm_a8d
	pop af
	ld [$ffb0], a
	pop af
	ld [$ffaf], a
	ret
; aa5

Functionaa5: ; aa5
	call Functiona57
	ld a, [$ffa9]
	and BUTTON_A | BUTTON_B
	jr z, Functionaa5
	ret
; aaf

Functionaaf: ; aaf
	ld a, [InLinkBattle]
	and a
	jr nz, .asm_ac1
	call Functionac6
	push de
	ld de, SFX_READ_TEXT_2
	call StartSFX
	pop de
	ret

.asm_ac1
	ld c, 65
	jp DelayFrames
; ac6

Functionac6: ; ac6
	ld a, [hOAMUpdate]
	push af
	ld a, $1
	ld [hOAMUpdate], a
	ld a, [InputType]
	or a
	jr z, .asm_ad9
	callba Function1de28a
.asm_ad9
	call Functionaf5
	call Functiona57
	ld a, [hJoyPressed]
	and $3
	jr nz, .asm_af1
	call RTC
	ld a, $1
	ld [hBGMapMode], a
	call DelayFrame
	jr .asm_ad9

.asm_af1
	pop af
	ld [hOAMUpdate], a
	ret
; af5

Functionaf5: ; af5
	ld a, [$ff9b]
	and $10
	jr z, .asm_aff
	ld a, $ee
	jr .asm_b02

.asm_aff
	ld a, [$c605]

.asm_b02
	ld [$c606], a
	ret
; b06

Functionb06: ; b06
	push bc
	ld a, [hl]
	ld b, a
	ld a, $ee
	cp b
	pop bc
	jr nz, .asm_b27
	ld a, [$ffaf]
	dec a
	ld [$ffaf], a
	ret nz
	ld a, [$ffb0]
	dec a
	ld [$ffb0], a
	ret nz
	ld a, $7a
	ld [hl], a
	ld a, $ff
	ld [$ffaf], a
	ld a, $6
	ld [$ffb0], a
	ret

.asm_b27
	ld a, [$ffaf]
	and a
	ret z
	dec a
	ld [$ffaf], a
	ret nz
	dec a
	ld [$ffaf], a
	ld a, [$ffb0]
	dec a
	ld [$ffb0], a
	ret nz
	ld a, $6
	ld [$ffb0], a
	ld a, $ee
	ld [hl], a
	ret
; b40