pokecrystal/home.asm

3418 lines
42 KiB
NASM

INCLUDE "includes.asm"
SECTION "NULL", ROM0[0]
NULL::
INCLUDE "rst.asm"
INCLUDE "interrupts.asm"
SECTION "Header", ROM0[$100]
Start::
nop
jp _Start
SECTION "Home", ROM0[$150]
INCLUDE "home/init.asm"
INCLUDE "home/vblank.asm"
INCLUDE "home/delay.asm"
INCLUDE "home/rtc.asm"
INCLUDE "home/fade.asm"
INCLUDE "home/lcd.asm"
INCLUDE "home/time.asm"
INCLUDE "home/serial.asm"
INCLUDE "home/joypad.asm"
INCLUDE "home/decompress.asm"
INCLUDE "home/palettes.asm"
INCLUDE "home/copy.asm"
INCLUDE "home/text.asm"
INCLUDE "home/video.asm"
INCLUDE "home/map_objects.asm"
INCLUDE "home/sine.asm"
INCLUDE "home/movement.asm"
INCLUDE "home/tilemap.asm"
INCLUDE "home/menu.asm"
INCLUDE "home/handshake.asm"
INCLUDE "home/game_time.asm"
INCLUDE "home/map.asm"
Function2d43:: ; 2d43
; Inexplicably empty.
; Seen in PredefPointers.
rept 16
nop
endr
ret
; 2d54
INCLUDE "home/farcall.asm"
INCLUDE "home/predef.asm"
INCLUDE "home/window.asm"
Function2e4e:: ; 2e4e
scf
ret
; 2e50
INCLUDE "home/flag.asm"
Function2ebb:: ; 2ebb
ld a, [$c2cc]
bit 1, a
ret z
ld a, [hJoyDown]
bit A_BUTTON, a
ret
; 2ec6
Function2ec6:: ; 2ec6
xor a
ret
; 2ec8
Function2ec8:: ; 2ec8
xor a
dec a
ret
; 2ecb
Function2ecb:: ; 2ecb
push hl
ld hl, $c2cc
bit 1, [hl]
pop hl
ret
; 2ed3
Function2ed3:: ; 0x2ed3
; disables overworld sprite updating?
xor a
ld [$ffde], a
ld a, [VramState]
res 0, a
ld [VramState], a
ld a, $0
ld [$c2ce], a
ret
; 0x2ee4
Function2ee4:: ; 2ee4
ld a, $1
ld [$c2ce], a
ld a, [VramState]
set 0, a
ld [VramState], a
ld a, $1
ld [$ffde], a
ret
; 2ef6
INCLUDE "home/string.asm"
IsInJohto:: ; 2f17
; Return 0 if the player is in Johto, and 1 in Kanto.
ld a, [MapGroup]
ld b, a
ld a, [MapNumber]
ld c, a
call GetWorldMapLocation
cp FAST_SHIP
jr z, .Johto
cp SPECIAL_MAP
jr nz, .CheckRegion
ld a, [BackupMapGroup]
ld b, a
ld a, [BackupMapNumber]
ld c, a
call GetWorldMapLocation
.CheckRegion
cp KANTO_LANDMARK
jr nc, .Kanto
.Johto
xor a
ret
.Kanto
ld a, 1
ret
; 2f3e
Function2f3e:: ; 2f3e
ret
; 2f3f
INCLUDE "home/item.asm"
INCLUDE "home/random.asm"
INCLUDE "home/sram.asm"
; Register aliases
_hl_:: ; 2fec
jp [hl]
; 2fed
_de_:: ; 2fed
push de
ret
; 2fef
INCLUDE "home/double_speed.asm"
ClearSprites:: ; 300b
; Erase OAM data
ld hl, Sprites
ld b, SpritesEnd - Sprites
xor a
.loop
ld [hli], a
dec b
jr nz, .loop
ret
; 3016
HideSprites:: ; 3016
; Set all OAM y-positions to 160 to hide them offscreen
ld hl, Sprites
ld de, 4 ; length of an OAM struct
ld b, (SpritesEnd - Sprites) / 4 ; number of OAM structs
ld a, 160 ; y
.loop
ld [hl], a
add hl, de
dec b
jr nz, .loop
ret
; 3026
INCLUDE "home/copy2.asm"
Function309d:: ; 309d
ld a, [rSVBK]
push af
ld a, 2
ld [rSVBK], a
ld hl, TileMap
ld de, $d000
ld bc, 360
call CopyBytes
pop af
ld [rSVBK], a
ret
; 30b4
Function30b4:: ; 30b4
xor a
ld [hBGMapMode], a
call Function30bf
ld a, 1
ld [hBGMapMode], a
ret
; 30bf
Function30bf:: ; 30bf
ld a, [rSVBK]
push af
ld a, 2
ld [rSVBK], a
ld hl, $d000
ld de, TileMap
ld bc, 360
call CopyBytes
pop af
ld [rSVBK], a
ret
; 30d6
CopyName1:: ; 30d6
ld hl, StringBuffer2
CopyName2:: ; 30d9
.loop
ld a, [de]
inc de
ld [hli], a
cp "@"
jr nz, .loop
ret
; 30e1
IsInArray:: ; 30e1
; Find value a for every de bytes in array hl.
; Return index in b and carry if found.
ld b, 0
ld c, a
.loop
ld a, [hl]
cp $ff
jr z, .NotInArray
cp c
jr z, .InArray
inc b
add hl, de
jr .loop
.NotInArray
and a
ret
.InArray
scf
ret
; 30f4
SkipNames:: ; 0x30f4
; skips n names where n = a
ld bc, $000b ; name length
and a
ret z
.loop
add hl, bc
dec a
jr nz, .loop
ret
; 0x30fe
AddNTimes:: ; 0x30fe
; adds bc n times where n = a
and a
ret z
.loop
add hl, bc
dec a
jr nz, .loop
ret
; 0x3105
INCLUDE "home/math.asm"
PrintLetterDelay:: ; 313d
; Wait before printing the next letter.
; The text speed setting in Options is actually a frame count:
; fast: 1 frame
; mid: 3 frames
; slow: 5 frames
; $cfcf[!0] and A or B override text speed with a one-frame delay.
; Options[4] and $cfcf[!1] disable the delay.
ld a, [Options]
bit NO_TEXT_SCROLL, a
ret nz
; non-scrolling text?
ld a, [$cfcf]
bit 1, a
ret z
push hl
push de
push bc
ld hl, hOAMUpdate
ld a, [hl]
push af
; orginally turned oam update off...
; ld a, 1
ld [hl], a
; force fast scroll?
ld a, [$cfcf]
bit 0, a
jr z, .fast
; text speed
ld a, [Options]
and %111
jr .updatedelay
.fast
ld a, 1
.updatedelay
ld [TextDelayFrames], a
.checkjoypad
call GetJoypad
; input override
ld a, [$c2d7]
and a
jr nz, .wait
; Wait one frame if holding A or B.
ld a, [hJoyDown]
bit 0, a ; A_BUTTON
jr z, .checkb
jr .delay
.checkb
bit 1, a ; B_BUTTON
jr z, .wait
.delay
call DelayFrame
jr .end
.wait
ld a, [TextDelayFrames]
and a
jr nz, .checkjoypad
.end
pop af
ld [hOAMUpdate], a
pop bc
pop de
pop hl
ret
; 318c
CopyDataUntil:: ; 318c
; Copy [hl .. bc) to [de .. de + bc - hl).
; In other words, the source data is
; from hl up to but not including bc,
; and the destination is de.
ld a, [hli]
ld [de], a
inc de
ld a, h
cp b
jr nz, CopyDataUntil
ld a, l
cp c
jr nz, CopyDataUntil
ret
; 0x3198
PrintNum:: ; 3198
ld a, [hROMBank]
push af
ld a, BANK(_PrintNum)
rst Bankswitch
call _PrintNum
pop af
rst Bankswitch
ret
; 31a4
Function31a4:: ; 31a4
ld a, [hROMBank]
push af
ld a, BANK(Function1061ef)
rst Bankswitch
call Function1061ef
pop af
rst Bankswitch
ret
; 31b0
FarPrintText:: ; 31b0
ld [hBuffer], a
ld a, [hROMBank]
push af
ld a, [hBuffer]
rst Bankswitch
call PrintText
pop af
rst Bankswitch
ret
; 31be
CallPointerAt:: ; 31be
ld a, [hROMBank]
push af
ld a, [hli]
rst Bankswitch
ld a, [hli]
ld h, [hl]
ld l, a
call _hl_
pop hl
ld a, h
rst Bankswitch
ret
; 31cd
Function31cd:: ; 31cd
; Push pointer hl in the current bank to $d0e8.
ld a, [hROMBank]
Function31cf:: ; 31cf
; Push pointer a:hl to $d0e8.
ld [$d0e8], a
ld a, l
ld [$d0e9], a
ld a, h
ld [$d0ea], a
ret
; 31db
StringCmp:: ; 31db
; Compare c bytes at de and hl.
; Return z if they all match.
ld a, [de]
cp [hl]
ret nz
inc de
inc hl
dec c
jr nz, StringCmp
ret
; 0x31e4
CompareLong:: ; 31e4
; Compare bc bytes at de and hl.
; Return carry if they all match.
ld a, [de]
cp [hl]
jr nz, .Diff
inc de
inc hl
dec bc
ld a, b
or c
jr nz, CompareLong
scf
ret
.Diff
and a
ret
; 31f3
WhiteBGMap:: ; 31f3
call ClearPalettes
WaitBGMap:: ; 31f6
; Tell VBlank to update BG Map
ld a, 1 ; BG Map 0 tiles
ld [hBGMapMode], a
; Wait for it to do its magic
ld c, 4
call DelayFrames
ret
; 3200
Function3200:: ; 0x3200
ld a, [hCGB]
and a
jr z, .asm_320e
ld a, 2
ld [hBGMapMode], a
ld c, 4
call DelayFrames
.asm_320e
ld a, 1
ld [hBGMapMode], a
ld c, 4
call DelayFrames
ret
; 0x3218
Function3218:: ; 3218
ld a, [hCGB]
and a
ret
; 321c
Function321c:: ; 321c
ld a, [hCGB]
and a
jr z, .asm_322e
ld a, [$c2ce]
cp 0
jr z, .asm_322e
ld a, 1
ld [hBGMapMode], a
jr Function323d
.asm_322e
ld a, 1
ld [hBGMapMode], a
ld c, 4
call DelayFrames
ret
; 3238
Function3238:: ; 3238
ld a, [hCGB]
and a
jr z, WaitBGMap
Function323d:: ; 323d
jr Function3246
; 323f
Function323f:: ; 323f
callba Function104000
ret
; 3246
Function3246:: ; 3246
ld a, [hBGMapMode]
push af
xor a
ld [hBGMapMode], a
ld a, [$ffde]
push af
xor a
ld [$ffde], a
.asm_3252
ld a, [rLY]
cp $7f
jr c, .asm_3252 ; 3256 $fa
di
ld a, $1
ld [rVBK], a
ld hl, AttrMap
call Function327b
ld a, $0
ld [rVBK], a
ld hl, TileMap
call Function327b
.asm_326d
ld a, [rLY]
cp $7f
jr c, .asm_326d ; 3271 $fa
ei
pop af
ld [$ffde], a
pop af
ld [hBGMapMode], a
ret
; 327b
Function327b:: ; 327b
ld [hSPBuffer], sp
ld sp, hl
ld a, [$ffd7]
ld h, a
ld l, $0
ld a, $12
ld [$ffd3], a
ld b, $2
ld c, $41
.asm_328c
pop de
rept 9
.loop\@
ld a, [$ff00+c]
and b
jr nz, .loop\@
ld [hl], e
inc l
ld [hl], d
inc l
pop de
endr
.asm_32de
ld a, [$ff00+c]
and b
jr nz, .asm_32de
ld [hl], e
inc l
ld [hl], d
inc l
ld de, $000c
add hl, de
ld a, [$ffd3]
dec a
ld [$ffd3], a
jr nz, .asm_328c
ld a, [hSPBuffer]
ld l, a
ld a, [$ffda]
ld h, a
ld sp, hl
ret
; 32f9
Function32f9:: ; 32f9
ld a, [hCGB]
and a
jr nz, .asm_3309
ld a, $e4
ld [rBGP], a
ld a, $d0
ld [rOBP0], a
ld [rOBP1], a
ret
.asm_3309
push de
ld a, $e4
call DmgToCgbBGPals
ld de, $e4e4
call DmgToCgbObjPals
pop de
ret
; 3317
ClearPalettes:: ; 3317
; Make all palettes white
; CGB: make all the palette colors white
ld a, [hCGB]
and a
jr nz, .cgb
; DMG: just change palettes to 0 (white)
xor a
ld [rBGP], a
ld [rOBP0], a
ld [rOBP1], a
ret
.cgb
ld a, [rSVBK]
push af
ld a, 5
ld [rSVBK], a
; Fill BGPals and OBPals with $ffff (white)
ld hl, BGPals
ld bc, $80
ld a, $ff
call ByteFill
pop af
ld [rSVBK], a
; Request palette update
ld a, 1
ld [hCGBPalUpdate], a
ret
; 333e
ClearSGB:: ; 333e
ld b, $ff
GetSGBLayout:: ; 3340
; load sgb packets unless dmg
ld a, [hCGB]
and a
jr nz, .dosgb
ld a, [hSGB]
and a
ret z
.dosgb
ld a, $31 ; LoadSGBLayout
jp Predef
; 334e
SetHPPal:: ; 334e
; Set palette for hp bar pixel length e at hl.
call GetHPPal
ld [hl], d
ret
; 3353
GetHPPal:: ; 3353
; Get palette for hp bar pixel length e in d.
ld d, 0 ; green
ld a, e
cp 24
ret nc
inc d ; yellow
cp 10
ret nc
inc d ; red
ret
; 335f
CountSetBits:: ; 0x335f
; Count the number of set bits in b bytes starting from hl.
; Return in a, c and [$d265].
ld c, 0
.next
ld a, [hli]
ld e, a
ld d, 8
.count
srl e
ld a, 0
adc c
ld c, a
dec d
jr nz, .count
dec b
jr nz, .next
ld a, c
ld [$d265], a
ret
; 0x3376
GetWeekday:: ; 3376
ld a, [CurDay]
.mod
sub 7
jr nc, .mod
add 7
ret
; 3380
INCLUDE "home/pokedex_flags.asm"
NamesPointers:: ; 33ab
dbw BANK(PokemonNames), PokemonNames
dbw BANK(MoveNames), MoveNames
dbw 0, 0
dbw BANK(ItemNames), ItemNames
dbw 0, PartyMonOT
dbw 0, OTPartyMonOT
dbw BANK(TrainerClassNames), TrainerClassNames
dbw $04, $4b52 ; ????
; 33c3
GetName:: ; 33c3
; Return name CurSpecies from name list $cf61 in StringBuffer1.
ld a, [hROMBank]
push af
push hl
push bc
push de
ld a, [$cf61]
cp 1 ; Pokemon names
jr nz, .NotPokeName
ld a, [CurSpecies]
ld [$d265], a
call GetPokemonName
ld hl, 11
add hl, de
ld e, l
ld d, h
jr .done
.NotPokeName
ld a, [$cf61]
dec a
ld e, a
ld d, 0
ld hl, NamesPointers
add hl, de
add hl, de
add hl, de
ld a, [hli]
rst Bankswitch
ld a, [hli]
ld h, [hl]
ld l, a
ld a, [CurSpecies]
dec a
call GetNthString
ld de, StringBuffer1
ld bc, $000d
call CopyBytes
.done
ld a, e
ld [$d102], a
ld a, d
ld [$d103], a
pop de
pop bc
pop hl
pop af
rst Bankswitch
ret
; 3411
GetNthString:: ; 3411
; Return the address of the
; ath string starting from hl.
and a
ret z
push bc
ld b, a
ld c, "@"
.readChar
ld a, [hli]
cp c
jr nz, .readChar
dec b
jr nz, .readChar
pop bc
ret
; 3420
GetBasePokemonName:: ; 3420
; Discards gender (Nidoran).
push hl
call GetPokemonName
ld hl, StringBuffer1
.loop
ld a, [hl]
cp "@"
jr z, .quit
cp "♂"
jr z, .end
cp "♀"
jr z, .end
inc hl
jr .loop
.end
ld [hl], "@"
.quit
pop hl
ret
; 343b
GetPokemonName:: ; 343b
; Get Pokemon name $d265.
ld a, [hROMBank]
push af
push hl
ld a, BANK(PokemonNames)
rst Bankswitch
; Each name is ten characters
ld a, [$d265]
dec a
ld d, 0
ld e, a
ld h, 0
ld l, a
add hl, hl
add hl, hl
add hl, de
add hl, hl
ld de, PokemonNames
add hl, de
; Terminator
ld de, StringBuffer1
push de
ld bc, PKMN_NAME_LENGTH - 1
call CopyBytes
ld hl, StringBuffer1 + PKMN_NAME_LENGTH - 1
ld [hl], "@"
pop de
pop hl
pop af
rst Bankswitch
ret
; 3468
GetItemName:: ; 3468
; Get item name $d265.
push hl
push bc
ld a, [$d265]
cp TM_01
jr nc, .TM
ld [CurSpecies], a
ld a, 4 ; Item names
ld [$cf61], a
call GetName
jr .Copied
.TM
call GetTMHMName
.Copied
ld de, StringBuffer1
pop bc
pop hl
ret
; 3487
GetTMHMName:: ; 3487
; Get TM/HM name by item id $d265.
push hl
push de
push bc
ld a, [$d265]
push af
; TM/HM prefix
cp HM_01
push af
jr c, .TM
ld hl, .HMText
ld bc, .HMTextEnd - .HMText
jr .asm_34a1
.TM
ld hl, .TMText
ld bc, .TMTextEnd - .TMText
.asm_34a1
ld de, StringBuffer1
call CopyBytes
; TM/HM number
push de
ld a, [$d265]
ld c, a
callab GetTMHMNumber
pop de
; HM numbers start from 51, not 1
pop af
ld a, c
jr c, .asm_34b9
sub NUM_TMS
; Divide and mod by 10 to get the top and bottom digits respectively
.asm_34b9
ld b, "0"
.mod10
sub 10
jr c, .asm_34c2
inc b
jr .mod10
.asm_34c2
add 10
push af
ld a, b
ld [de], a
inc de
pop af
ld b, "0"
add b
ld [de], a
; End the string
inc de
ld a, "@"
ld [de], a
pop af
ld [$d265], a
pop bc
pop de
pop hl
ret
.TMText
db "TM"
.TMTextEnd
db "@"
.HMText
db "HM"
.HMTextEnd
db "@"
; 34df
IsHM:: ; 34df
cp HM_01
jr c, .NotHM
scf
ret
.NotHM
and a
ret
; 34e7
IsHMMove:: ; 34e7
ld hl, .HMMoves
ld de, 1
jp IsInArray
.HMMoves
db CUT
db FLY
db SURF
db STRENGTH
db FLASH
db WATERFALL
db WHIRLPOOL
db $ff
; 34f8
GetMoveName:: ; 34f8
push hl
; move name
ld a, $2 ; move names
ld [$cf61], a
; move id
ld a, [$d265]
ld [CurSpecies], a
call GetName
ld de, StringBuffer1
pop hl
ret
; 350c
Function350c:: ; 350c
call Function1c66
ld a, [hROMBank]
push af
ld a, $9
rst Bankswitch
call Function245af
call Function3524
call Function245cb
pop af
rst Bankswitch
ld a, [$cf73]
ret
; 3524
Function3524:: ; 3524
ld hl, VramState
bit 0, [hl]
jp nz, UpdateTimePals
jp Function32f9
; 352f
Function352f:: ; 352f
ld a, [$cf82]
dec a
ld b, a
ld a, [$cf84]
sub b
ld d, a
ld a, [$cf83]
dec a
ld c, a
ld a, [$cf85]
sub c
ld e, a
push de
call GetTileCoord
pop bc
jp TextBox
; 354b
Function354b:: ; 354b
call DelayFrame
ld a, [$ffaa]
push af
ld a, $1
ld [$ffaa], a
call Functiona57
pop af
ld [$ffaa], a
ld a, [$ffa9]
and $f0
ld c, a
ld a, [hJoyPressed]
and $f
or c
ld c, a
ret
; 3567
Function3567:: ; 3567
ld a, [hROMBank]
push af
call Function2c52
call Function3574
pop bc
ld a, b
rst Bankswitch
ret
; 3574
Function3574:: ; 3574
ld hl, $0001
add hl, de
ld a, [hl]
cp $ff
jr z, .asm_3597
ld l, a
push hl
call Function3599
pop hl
jr nc, .asm_3597
ld d, a
ld e, l
call Function35de
jr nc, .asm_3597
call Function2631
callba Function96c56
scf
ret
.asm_3597
and a
ret
; 3599
Function3599:: ; 3599
push de
ld hl, $0010
add hl, de
ld a, [hl]
ld hl, $0011
add hl, de
ld e, [hl]
sub $4
ld d, a
ld a, e
sub $4
ld e, a
call Function35b0
pop de
ret
; 35b0
Function35b0:: ; 35b0
ld hl, $dbfc
ld a, [hli]
ld h, [hl]
ld l, a
ld a, [$dbfb]
and a
jr z, .asm_35d3
.asm_35bc
push af
ld a, [hl]
cp e
jr nz, .asm_35c8
inc hl
ld a, [hld]
cp d
jr nz, .asm_35c8
jr .asm_35d5
.asm_35c8
ld a, $5
add l
ld l, a
jr nc, .asm_35cf
inc h
.asm_35cf
pop af
dec a
jr nz, .asm_35bc
.asm_35d3
and a
ret
.asm_35d5
pop af
ld d, a
ld a, [$dbfb]
sub d
inc a
scf
ret
; 35de
Function35de:: ; 35de
inc e
ld hl, $0001
add hl, bc
ld a, [hli]
ld h, [hl]
ld l, a
.asm_35e6
ld a, [hli]
cp $ff
jr z, .asm_35fc
cp d
jr nz, .asm_35f7
ld a, [hli]
cp e
jr nz, .asm_35f8
ld a, [hli]
ld h, [hl]
ld l, a
jr .asm_35fe
.asm_35f7
inc hl
.asm_35f8
inc hl
inc hl
jr .asm_35e6
.asm_35fc
and a
ret
.asm_35fe
scf
ret
; 3600
CheckTrainerBattle2:: ; 3600
ld a, [hROMBank]
push af
call Function2c52
call CheckTrainerBattle
pop bc
ld a, b
rst Bankswitch
ret
; 360d
CheckTrainerBattle:: ; 360d
; Check if any trainer on the map sees the player and wants to battle.
; Skip the player object.
ld a, 1
ld de, MapObjects + OBJECT_LENGTH
.loop
; Start a battle if the object:
push af
push de
; Has a sprite
ld hl, $0001
add hl, de
ld a, [hl]
and a
jr z, .next
; Is a trainer
ld hl, $0008
add hl, de
ld a, [hl]
and $f
cp $2
jr nz, .next
; Is visible on the map
ld hl, $0000
add hl, de
ld a, [hl]
cp $ff
jr z, .next
; Is facing the player...
call Function1ae5
call FacingPlayerDistance_bc
jr nc, .next
; ...within their sight range
ld hl, $0009
add hl, de
ld a, [hl]
cp b
jr c, .next
; And hasn't already been beaten
push bc
push de
ld hl, $000a
add hl, de
ld a, [hli]
ld h, [hl]
ld l, a
ld e, [hl]
inc hl
ld d, [hl]
ld b, CHECK_FLAG
call EventFlagAction
ld a, c
pop de
pop bc
and a
jr z, .asm_3666
.next
pop de
ld hl, OBJECT_LENGTH
add hl, de
ld d, h
ld e, l
pop af
inc a
cp NUM_OBJECTS
jr nz, .loop
xor a
ret
.asm_3666
pop de
pop af
ld [$ffe0], a
ld a, b
ld [$d03f], a
ld a, c
ld [MartPointer], a
jr Function367e
; 3674
Function3674:: ; 3674
ld a, $1
ld [$d03f], a
ld a, $ff
ld [MartPointer], a
Function367e:: ; 367e
call GetMapScriptHeaderBank
ld [EngineBuffer1], a
ld a, [$ffe0]
call GetMapObject
ld hl, $000a
add hl, bc
ld a, [EngineBuffer1]
call GetFarHalfword
ld de, $d041
ld bc, $000d
ld a, [EngineBuffer1]
call FarCopyBytes
xor a
ld [$d04d], a
scf
ret
; 36a5
FacingPlayerDistance_bc:: ; 36a5
push de
call FacingPlayerDistance
ld b, d
ld c, e
pop de
ret
; 36ad
FacingPlayerDistance:: ; 36ad
; Return carry if the sprite at bc is facing the player,
; and its distance in d.
ld hl, $0010 ; x
add hl, bc
ld d, [hl]
ld hl, $0011 ; y
add hl, bc
ld e, [hl]
ld a, [MapX]
cp d
jr z, .CheckY
ld a, [MapY]
cp e
jr z, .CheckX
and a
ret
.CheckY
ld a, [MapY]
sub e
jr z, .NotFacing
jr nc, .Above
; Below
cpl
inc a
ld d, a
ld e, UP << 2
jr .CheckFacing
.Above
ld d, a
ld e, DOWN << 2
jr .CheckFacing
.CheckX
ld a, [MapX]
sub d
jr z, .NotFacing
jr nc, .Left
; Right
cpl
inc a
ld d, a
ld e, LEFT << 2
jr .CheckFacing
.Left
ld d, a
ld e, RIGHT << 2
.CheckFacing
call GetSpriteDirection
cp e
jr nz, .NotFacing
scf
ret
.NotFacing
and a
ret
; 36f5
Function36f5:: ; 36f5
push bc
ld hl, $0001
add hl, bc
ld a, [hl]
call GetMapObject
ld hl, $000a
add hl, bc
ld a, [hli]
ld h, [hl]
ld l, a
call GetMapScriptHeaderBank
call GetFarHalfword
ld d, h
ld e, l
push de
ld b, $2
call EventFlagAction
pop de
ld a, c
and a
pop bc
ret
; 3718
Function3718:: ; 3718
ld a, [BattleType]
cp $1
jr .asm_3724
ld hl, WalkingTile
jr .asm_3731
.asm_3724
ld a, [$d0ee]
ld hl, WalkingTile
and $f
jr z, .asm_3731
ld hl, $d049
.asm_3731
ld a, [hli]
ld h, [hl]
ld l, a
call GetMapScriptHeaderBank
call FarPrintText
call WaitBGMap
call Functiona80
ret
; 3741
IsAPokemon:: ; 3741
; Return carry if species a is not a Pokemon.
and a
jr z, .NotAPokemon
cp EGG
jr z, .Pokemon
cp NUM_POKEMON + 1
jr c, .Pokemon
.NotAPokemon
scf
ret
.Pokemon
and a
ret
; 3750
DrawHPBar:: ; 3750
; Draw an HP bar d tiles long at hl
; Fill it up to e pixels
push hl
push de
push bc
; Place 'HP:'
ld a, $60
ld [hli], a
ld a, $61
ld [hli], a
; Draw a template
push hl
ld a, $62 ; empty bar
.template
ld [hli], a
dec d
jr nz, .template
ld a, $6b ; bar end
add b
ld [hl], a
pop hl
; Safety check # pixels
ld a, e
and a
jr nz, .fill
ld a, c
and a
jr z, .done
ld e, 1
.fill
; Keep drawing tiles until pixel length is reached
ld a, e
sub TILE_WIDTH
jr c, .lastbar
ld e, a
ld a, $6a ; full bar
ld [hli], a
ld a, e
and a
jr z, .done
jr .fill
.lastbar
ld a, $62 ; empty bar
add e ; + e
ld [hl], a
.done
pop bc
pop de
pop hl
ret
; 3786
Function3786:: ; 3786
ld a, $1
ld [$c2c6], a
Function378b:: ; 378b
ld a, [CurPartySpecies]
call IsAPokemon
jr c, .asm_37ad
push hl
ld de, VTiles2
ld a, $3c
call Predef
pop hl
xor a
ld [$ffad], a
ld bc, $0707
ld a, $13
call Predef
xor a
ld [$c2c6], a
ret
.asm_37ad
xor a
ld [$c2c6], a
inc a
ld [CurPartySpecies], a
ret
; 37b6
Function37b6:: ; 37b6
push af
ld a, $1
ld [$c2bc], a
pop af
call Function37e2
call WaitSFX
ret
; 37c4
Function37c4:: ; 37c4
push af
ld a, $1
ld [$c2bc], a
pop af
jp Function37e2
; 37ce
Function37ce:: ; 37ce
call Function37d5
call WaitSFX
ret
; 37d5
Function37d5:: ; 37d5
push af
xor a
ld [$c2bc], a
ld [CryTracks], a
pop af
call Function37e2
ret
; 37e2
Function37e2:: ; 37e2
push hl
push de
push bc
call Function381e
jr c, .asm_37ef
ld e, c
ld d, b
call PlayCryHeader
.asm_37ef
pop bc
pop de
pop hl
ret
; 37f3
Function37f3:: ; 37f3
call Function381e
ret c
ld a, [hROMBank]
push af
ld a, BANK(CryHeaders)
rst Bankswitch
ld hl, CryHeaders
add hl, bc
add hl, bc
add hl, bc
add hl, bc
add hl, bc
add hl, bc
ld e, [hl]
inc hl
ld d, [hl]
inc hl
ld a, [hli]
ld [CryPitch], a
ld a, [hli]
ld [CryEcho], a
ld a, [hli]
ld [CryLength], a
ld a, [hl]
ld [CryLength + 1], a
pop af
rst Bankswitch
and a
ret
; 381e
Function381e:: ; 381e
and a
jr z, .asm_382b
cp NUM_POKEMON + 1
jr nc, .asm_382b
dec a
ld c, a
ld b, 0
and a
ret
.asm_382b
scf
ret
; 382d
PrintLevel:: ; 382d
; Print TempMonLevel at hl
ld a, [TempMonLevel]
ld [hl], $6e ; ":L"
inc hl
; How many digits?
ld c, 2
cp 100
jr c, Function3842
; 3-digit numbers overwrite the :L.
dec hl
inc c
jr Function3842
; 383d
Function383d:: ; 383d
; Print :L and all 3 digits
ld [hl], $6e
inc hl
ld c, 3
; 3842
Function3842:: ; 3842
ld [$d265], a
ld de, $d265
ld b, %01000001 ; flags
jp PrintNum
; 384d
Function384d:: ; 384d
ld hl, $d25e
ld c, a
ld b, $0
add hl, bc
ld a, [hl]
ret
; 3856
GetBaseData:: ; 3856
push bc
push de
push hl
ld a, [hROMBank]
push af
ld a, BANK(BaseData)
rst Bankswitch
; Egg doesn't have BaseData
ld a, [CurSpecies]
cp EGG
jr z, .egg
; Get BaseData
dec a
ld bc, BaseData1 - BaseData0
ld hl, BaseData
call AddNTimes
ld de, CurBaseData
ld bc, BaseData1 - BaseData0
call CopyBytes
jr .end
.egg
; ????
ld de, UnknownEggPic
; Sprite dimensions
ld b, $55 ; 5x5
ld hl, BasePicSize
ld [hl], b
; ????
ld hl, BasePadding
ld [hl], e
inc hl
ld [hl], d
inc hl
ld [hl], e
inc hl
ld [hl], d
jr .end
.end
; Replace Pokedex # with species
ld a, [CurSpecies]
ld [BaseDexNo], a
pop af
rst Bankswitch
pop hl
pop de
pop bc
ret
; 389c
GetCurNick:: ; 389c
ld a, [CurPartyMon]
ld hl, PartyMonNicknames
GetNick:: ; 38a2
; Get nickname a from list hl.
push hl
push bc
call SkipNames
ld de, StringBuffer1
push de
ld bc, PKMN_NAME_LENGTH
call CopyBytes
pop de
callab CheckNickErrors
pop bc
pop hl
ret
; 38bb
PrintBCDNumber:: ; 38bb
; function to print a BCD (Binary-coded decimal) number
; de = address of BCD number
; hl = destination address
; c = flags and length
; bit 7: if set, do not print leading zeroes
; if unset, print leading zeroes
; bit 6: if set, left-align the string (do not pad empty digits with spaces)
; if unset, right-align the string
; bit 5: if set, print currency symbol at the beginning of the string
; if unset, do not print the currency symbol
; bits 0-4: length of BCD number in bytes
; Note that bits 5 and 7 are modified during execution. The above reflects
; their meaning at the beginning of the functions's execution.
ld b, c ; save flags in b
res 7, c
res 6, c
res 5, c ; c now holds the length
bit 5, b
jr z, .loop
bit 7, b
jr nz, .loop
ld [hl], "¥"
inc hl
.loop
ld a, [de]
swap a
call PrintBCDDigit ; print upper digit
ld a, [de]
call PrintBCDDigit ; print lower digit
inc de
dec c
jr nz, .loop
bit 7, b ; were any non-zero digits printed?
jr z, .done ; if so, we are done
.numberEqualsZero ; if every digit of the BCD number is zero
bit 6, b ; left or right alignment?
jr nz, .skipRightAlignmentAdjustment
dec hl ; if the string is right-aligned, it needs to be moved back one space
.skipRightAlignmentAdjustment
bit 5, b
jr z, .skipCurrencySymbol
ld [hl], "¥" ; currency symbol
inc hl
.skipCurrencySymbol
ld [hl], "0"
call PrintLetterDelay
inc hl
.done
ret
; 0x38f2
PrintBCDDigit:: ; 38f2
and a, %00001111
and a
jr z, .zeroDigit
.nonzeroDigit
bit 7, b ; have any non-space characters been printed?
jr z, .outputDigit
; if bit 7 is set, then no numbers have been printed yet
bit 5, b ; print the currency symbol?
jr z, .skipCurrencySymbol
ld [hl], "¥"
inc hl
res 5, b
.skipCurrencySymbol
res 7, b ; unset 7 to indicate that a nonzero digit has been reached
.outputDigit
add a, "0"
ld [hli], a
jp PrintLetterDelay
.zeroDigit
bit 7, b ; either printing leading zeroes or already reached a nonzero digit?
jr z, .outputDigit ; if so, print a zero digit
bit 6, b ; left or right alignment?
ret nz
ld a, " "
ld [hli], a ; if right-aligned, "print" a space by advancing the pointer
ret
; 0x3917
GetPartyParamLocation:: ; 3917
; Get the location of parameter a from CurPartyMon in hl
push bc
ld hl, PartyMons
ld c, a
ld b, 0
add hl, bc
ld a, [CurPartyMon]
call GetPartyLocation
pop bc
ret
; 3927
GetPartyLocation:: ; 3927
; Add the length of a PartyMon struct to hl a times.
ld bc, PartyMon2 - PartyMon1
jp AddNTimes
; 392d
Function392d:: ; 392d
push hl
ld a, b
dec a
ld b, 0
add hl, bc
ld hl, BaseData + 0
ld bc, $0020
call AddNTimes
ld a, BANK(BaseData)
call GetFarHalfword
ld b, l
ld c, h
pop hl
ret
; 3945
UserPartyAttr:: ; 3945
push af
ld a, [hBattleTurn]
and a
jr nz, .asm_394e
pop af
jr BattlePartyAttr
.asm_394e
pop af
jr OTPartyAttr
; 3951
OpponentPartyAttr:: ; 3951
push af
ld a, [hBattleTurn]
and a
jr z, .asm_395a
pop af
jr BattlePartyAttr
.asm_395a
pop af
jr OTPartyAttr
; 395d
BattlePartyAttr:: ; 395d
; Get attribute a from the active BattleMon's party struct.
push bc
ld c, a
ld b, 0
ld hl, PartyMons
add hl, bc
ld a, [CurBattleMon]
call GetPartyLocation
pop bc
ret
; 396d
OTPartyAttr:: ; 396d
; Get attribute a from the active EnemyMon's party struct.
push bc
ld c, a
ld b, 0
ld hl, OTPartyMon1Species
add hl, bc
ld a, [CurOTMon]
call GetPartyLocation
pop bc
ret
; 397d
ResetDamage:: ; 397d
xor a
ld [CurDamage], a
ld [CurDamage + 1], a
ret
; 3985
SetPlayerTurn:: ; 3985
xor a
ld [hBattleTurn], a
ret
; 3989
SetEnemyTurn:: ; 3989
ld a, 1
ld [hBattleTurn], a
ret
; 398e
UpdateOpponentInParty:: ; 398e
ld a, [hBattleTurn]
and a
jr z, UpdateEnemyMonInParty
jr UpdateBattleMonInParty
; 3995
UpdateUserInParty:: ; 3995
ld a, [hBattleTurn]
and a
jr z, UpdateBattleMonInParty
jr UpdateEnemyMonInParty
; 399c
UpdateBattleMonInParty:: ; 399c
; Update level, status, current HP
ld a, [CurBattleMon]
Function399f:: ; 399f
ld hl, PartyMon1Level
call GetPartyLocation
ld d, h
ld e, l
ld hl, BattleMonLevel
ld bc, BattleMonMaxHP - BattleMonLevel
jp CopyBytes
; 39b0
UpdateEnemyMonInParty:: ; 39b0
; Update level, status, current HP
; No wildmons.
ld a, [IsInBattle]
dec a
ret z
ld a, [CurOTMon]
ld hl, OTPartyMon1Level
call GetPartyLocation
ld d, h
ld e, l
ld hl, EnemyMonLevel
ld bc, EnemyMonMaxHP - EnemyMonLevel
jp CopyBytes
; 39c9
RefreshBattleHuds:: ; 39c9
call UpdateBattleHuds
ld c, 3
call DelayFrames
jp WaitBGMap
; 39d4
UpdateBattleHuds:: ; 39d4
callba Function3df48
callba Function3e036
ret
; 39e1
GetBattleVar:: ; 39e1
; Preserves hl.
push hl
call _GetBattleVar
pop hl
ret
; 39e7
_GetBattleVar:: ; 39e7
; Get variable from pair a, depending on whose turn it is.
; There are 21 variable pairs.
push bc
ld hl, .battlevarpairs
ld c, a
ld b, 0
add hl, bc
add hl, bc
ld a, [hli]
ld h, [hl]
ld l, a
; Enemy turn uses the second byte instead.
; This lets battle variable calls be side-neutral.
ld a, [hBattleTurn]
and a
jr z, .getvar
inc hl
.getvar
; var id
ld a, [hl]
ld c, a
ld b, 0
ld hl, .vars
add hl, bc
add hl, bc
ld a, [hli]
ld h, [hl]
ld l, a
ld a, [hl]
pop bc
ret
.battlevarpairs
dw .substatus1, .substatus2, .substatus3, .substatus4, .substatus5
dw .substatus1opp, .substatus2opp, .substatus3opp, .substatus4opp, .substatus5opp
dw .status, .statusopp, .animation, .effect, .power, .type
dw .curmove, .lastcounter, .lastcounteropp, .lastmove, .lastmoveopp
const_def
const PLAYER_SUBSTATUS_1
const ENEMY_SUBSTATUS_1
const PLAYER_SUBSTATUS_2
const ENEMY_SUBSTATUS_2
const PLAYER_SUBSTATUS_3
const ENEMY_SUBSTATUS_3
const PLAYER_SUBSTATUS_4
const ENEMY_SUBSTATUS_4
const PLAYER_SUBSTATUS_5
const ENEMY_SUBSTATUS_5
const PLAYER_STATUS
const ENEMY_STATUS
const PLAYER_MOVE_ANIMATION
const ENEMY_MOVE_ANIMATION
const PLAYER_MOVE_EFFECT
const ENEMY_MOVE_EFFECT
const PLAYER_MOVE_POWER
const ENEMY_MOVE_POWER
const PLAYER_MOVE_TYPE
const ENEMY_MOVE_TYPE
const PLAYER_CUR_MOVE
const ENEMY_CUR_MOVE
const PLAYER_COUNTER_MOVE
const ENEMY_COUNTER_MOVE
const PLAYER_LAST_MOVE
const ENEMY_LAST_MOVE
; player enemy
.substatus1 db PLAYER_SUBSTATUS_1, ENEMY_SUBSTATUS_1
.substatus1opp db ENEMY_SUBSTATUS_1, PLAYER_SUBSTATUS_1
.substatus2 db PLAYER_SUBSTATUS_2, ENEMY_SUBSTATUS_2
.substatus2opp db ENEMY_SUBSTATUS_2, PLAYER_SUBSTATUS_2
.substatus3 db PLAYER_SUBSTATUS_3, ENEMY_SUBSTATUS_3
.substatus3opp db ENEMY_SUBSTATUS_3, PLAYER_SUBSTATUS_3
.substatus4 db PLAYER_SUBSTATUS_4, ENEMY_SUBSTATUS_4
.substatus4opp db ENEMY_SUBSTATUS_4, PLAYER_SUBSTATUS_4
.substatus5 db PLAYER_SUBSTATUS_5, ENEMY_SUBSTATUS_5
.substatus5opp db ENEMY_SUBSTATUS_5, PLAYER_SUBSTATUS_5
.status db PLAYER_STATUS, ENEMY_STATUS
.statusopp db ENEMY_STATUS, PLAYER_STATUS
.animation db PLAYER_MOVE_ANIMATION, ENEMY_MOVE_ANIMATION
.effect db PLAYER_MOVE_EFFECT, ENEMY_MOVE_EFFECT
.power db PLAYER_MOVE_POWER, ENEMY_MOVE_POWER
.type db PLAYER_MOVE_TYPE, ENEMY_MOVE_TYPE
.curmove db PLAYER_CUR_MOVE, ENEMY_CUR_MOVE
.lastcounter db PLAYER_COUNTER_MOVE, ENEMY_COUNTER_MOVE
.lastcounteropp db ENEMY_COUNTER_MOVE, PLAYER_COUNTER_MOVE
.lastmove db PLAYER_LAST_MOVE, ENEMY_LAST_MOVE
.lastmoveopp db ENEMY_LAST_MOVE, PLAYER_LAST_MOVE
.vars
dw PlayerSubStatus1, EnemySubStatus1
dw PlayerSubStatus2, EnemySubStatus2
dw PlayerSubStatus3, EnemySubStatus3
dw PlayerSubStatus4, EnemySubStatus4
dw PlayerSubStatus5, EnemySubStatus5
dw BattleMonStatus, EnemyMonStatus
dw PlayerMoveAnimation, EnemyMoveAnimation
dw PlayerMoveEffect, EnemyMoveEffect
dw PlayerMovePower, EnemyMovePower
dw PlayerMoveType, EnemyMoveType
dw CurPlayerMove, CurEnemyMove
dw LastEnemyCounterMove, LastPlayerCounterMove
dw LastPlayerMove, LastEnemyMove
; 3a90
Function3a90:: ; 3a90
inc hl
ld a, [hROMBank]
push af
ld a, [hli]
ld e, a
ld a, [hli]
ld d, a
ld a, [hli]
ld [hROMBank], a
ld [MBC3RomBank], a
ld a, e
ld l, a
ld a, d
ld h, a
ld de, $d00c
ld bc, $0028
call CopyBytes
pop af
ld [hROMBank], a
ld [MBC3RomBank], a
ret
; 3ab2
MobileTextBorder:: ; 3ab2
; For mobile link battles only.
ld a, [InLinkBattle]
cp 4
ret c
; Draw a cell phone icon at the top right corner of the border.
ld hl, $c5a3 ; TileMap(19,12)
ld [hl], $5e ; cell phone top
ld hl, $c5b7 ; TileMap(19,13)
ld [hl], $5f ; cell phone bottom
ret
; 3ac3
BattleTextBox:: ; 3ac3
; Open a textbox and print text at hl.
push hl
call SpeechTextBox
call MobileTextBorder
call Function1ad2
call Function321c
pop hl
call PrintTextBoxText
ret
; 3ad5
StdBattleTextBox:: ; 3ad5
; Open a textbox and print battle text at 20:hl.
GLOBAL BattleText
ld a, [hROMBank]
push af
ld a, BANK(BattleText)
rst Bankswitch
call BattleTextBox
pop af
rst Bankswitch
ret
; 3ae1
Function3ae1:: ; 3ae1
GLOBAL BattleAnimations
GLOBAL BattleAnimCommands
ld a, BANK(BattleAnimations)
rst Bankswitch
ld a, [hli]
ld [BattleAnimAddress], a
ld a, [hl]
ld [BattleAnimAddress + 1], a
ld a, BANK(BattleAnimCommands)
rst Bankswitch
ret
; 3af0
GetBattleAnimByte:: ; 3af0
push hl
push de
ld hl, BattleAnimAddress
ld e, [hl]
inc hl
ld d, [hl]
ld a, BANK(BattleAnimations)
rst Bankswitch
ld a, [de]
ld [BattleAnimByte], a
inc de
ld a, BANK(BattleAnimCommands)
rst Bankswitch
ld [hl], d
dec hl
ld [hl], e
pop de
pop hl
ld a, [BattleAnimByte]
ret
; 3b0c
Function3b0c:: ; 3b0c
ld a, [hLCDStatCustom]
and a
ret z
ld a, LYOverridesBackup % $100
ld [Requested2bppSource], a
ld a, LYOverridesBackup / $100
ld [Requested2bppSource + 1], a
ld a, LYOverrides % $100
ld [Requested2bppDest], a
ld a, LYOverrides / $100
ld [Requested2bppDest + 1], a
ld a, (LYOverridesEnd - LYOverrides) / 16
ld [Requested2bpp], a
ret
; 3b2a
Function3b2a:: ; 3b2a
ld [$c3b8], a
ld a, [hROMBank]
push af
ld a, BANK(Function8cfd6)
rst Bankswitch
ld a, [$c3b8]
call Function8cfd6
pop af
rst Bankswitch
ret
; 3b3c
Function3b3c:: ; 3b3c
ld [$c3b8], a
ld a, [hROMBank]
push af
ld a, BANK(Function8d120)
rst Bankswitch
ld a, [$c3b8]
call Function8d120
pop af
rst Bankswitch
ret
; 3b4e
SoundRestart:: ; 3b4e
push hl
push de
push bc
push af
ld a, [hROMBank]
push af
ld a, BANK(_SoundRestart)
ld [hROMBank], a
ld [MBC3RomBank], a
call _SoundRestart
pop af
ld [hROMBank], a
ld [MBC3RomBank], a
pop af
pop bc
pop de
pop hl
ret
; 3b6a
UpdateSound:: ; 3b6a
push hl
push de
push bc
push af
ld a, [hROMBank]
push af
ld a, BANK(_UpdateSound)
ld [hROMBank], a
ld [MBC3RomBank], a
call _UpdateSound
pop af
ld [hROMBank], a
ld [MBC3RomBank], a
pop af
pop bc
pop de
pop hl
ret
; 3b86
_LoadMusicByte:: ; 3b86
; CurMusicByte = [a:de]
GLOBAL LoadMusicByte
ld [hROMBank], a
ld [MBC3RomBank], a
ld a, [de]
ld [CurMusicByte], a
ld a, BANK(LoadMusicByte)
ld [hROMBank], a
ld [MBC3RomBank], a
ret
; 3b97
PlayMusic:: ; 3b97
; Play music de.
push hl
push de
push bc
push af
ld a, [hROMBank]
push af
ld a, BANK(_PlayMusic) ; and BANK(_SoundRestart)
ld [hROMBank], a
ld [MBC3RomBank], a
ld a, e
and a
jr z, .nomusic
call _PlayMusic
jr .end
.nomusic
call _SoundRestart
.end
pop af
ld [hROMBank], a
ld [MBC3RomBank], a
pop af
pop bc
pop de
pop hl
ret
; 3bbc
PlayMusic2:: ; 3bbc
; Stop playing music, then play music de.
push hl
push de
push bc
push af
ld a, [hROMBank]
push af
ld a, BANK(_PlayMusic)
ld [hROMBank], a
ld [MBC3RomBank], a
push de
ld de, MUSIC_NONE
call _PlayMusic
call DelayFrame
pop de
call _PlayMusic
pop af
ld [hROMBank], a
ld [MBC3RomBank], a
pop af
pop bc
pop de
pop hl
ret
; 3be3
PlayCryHeader:: ; 3be3
; Play a cry given parameters in header de
push hl
push de
push bc
push af
; Save current bank
ld a, [hROMBank]
push af
; Cry headers are stuck in one bank.
ld a, BANK(CryHeaders)
ld [hROMBank], a
ld [MBC3RomBank], a
; Each header is 6 bytes long:
ld hl, CryHeaders
add hl, de
add hl, de
add hl, de
add hl, de
add hl, de
add hl, de
ld e, [hl]
inc hl
ld d, [hl]
inc hl
ld a, [hli]
ld [CryPitch], a
ld a, [hli]
ld [CryEcho], a
ld a, [hli]
ld [CryLength], a
ld a, [hl]
ld [CryLength+1], a
ld a, BANK(PlayCry)
ld [hROMBank], a
ld [MBC3RomBank], a
call PlayCry
pop af
ld [hROMBank], a
ld [MBC3RomBank], a
pop af
pop bc
pop de
pop hl
ret
; 3c23
PlaySFX:: ; 3c23
; Play sound effect de.
; Sound effects are ordered by priority (lowest to highest)
push hl
push de
push bc
push af
; Is something already playing?
call CheckSFX
jr nc, .play
; Does it have priority?
ld a, [CurSFX]
cp e
jr c, .quit
.play
ld a, [hROMBank]
push af
ld a, BANK(_PlaySFX)
ld [hROMBank], a
ld [MBC3RomBank], a ; bankswitch
ld a, e
ld [CurSFX], a
call _PlaySFX
pop af
ld [hROMBank], a
ld [MBC3RomBank], a ; bankswitch
.quit
pop af
pop bc
pop de
pop hl
ret
; 3c4e
WaitPlaySFX:: ; 3c4e
call WaitSFX
call PlaySFX
ret
; 3c55
WaitSFX:: ; 3c55
; infinite loop until sfx is done playing
push hl
.loop
; ch5 on?
ld hl, Channel5 + Channel1Flags - Channel1
bit 0, [hl]
jr nz, .loop
; ch6 on?
ld hl, Channel6 + Channel1Flags - Channel1
bit 0, [hl]
jr nz, .loop
; ch7 on?
ld hl, Channel7 + Channel1Flags - Channel1
bit 0, [hl]
jr nz, .loop
; ch8 on?
ld hl, Channel8 + Channel1Flags - Channel1
bit 0, [hl]
jr nz, .loop
pop hl
ret
; 3c74
Function3c74:: ; 3c74
push hl
ld hl, $c1cc
bit 0, [hl]
jr nz, .asm_3c94
ld hl, $c1fe
bit 0, [hl]
jr nz, .asm_3c94
ld hl, $c230
bit 0, [hl]
jr nz, .asm_3c94
ld hl, $c262
bit 0, [hl]
jr nz, .asm_3c94
pop hl
scf
ret
.asm_3c94
pop hl
and a
ret
; 3c97
MaxVolume:: ; 3c97
ld a, $77 ; max
ld [Volume], a
ret
; 3c9d
LowVolume:: ; 3c9d
ld a, $33 ; 40%
ld [Volume], a
ret
; 3ca3
VolumeOff:: ; 3ca3
xor a
ld [Volume], a
ret
; 3ca8
Function3ca8:: ; 3ca8
ld a, $4
ld [MusicFade], a
ret
; 3cae
Function3cae:: ; 3cae
ld a, $84
ld [MusicFade], a
ret
; 3cb4
Function3cb4:: ; 3cb4
.asm_3cb4
and a
ret z
dec a
call UpdateSound
jr .asm_3cb4
; 3cbc
Function3cbc:: ; 3cbc
push hl
push de
push bc
push af
call Function3d97
ld a, [CurMusic]
cp e
jr z, .asm_3cda
ld a, $8
ld [MusicFade], a
ld a, e
ld [MusicFadeIDLo], a
ld a, d
ld [MusicFadeIDHi], a
ld a, e
ld [CurMusic], a
.asm_3cda
pop af
pop bc
pop de
pop hl
ret
; 3cdf
Function3cdf:: ; 3cdf
push hl
push de
push bc
push af
call Function3d97
ld a, [CurMusic]
cp e
jr z, .asm_3cfe
push de
ld de, MUSIC_NONE
call PlayMusic
call DelayFrame
pop de
ld a, e
ld [CurMusic], a
call PlayMusic
.asm_3cfe
pop af
pop bc
pop de
pop hl
ret
; 3d03
Function3d03:: ; 3d03
push hl
push de
push bc
push af
xor a
ld [$c2c1], a
ld de, MUSIC_BICYCLE
ld a, [PlayerState]
cp $1
jr z, .asm_3d18
call Function3d97
.asm_3d18
push de
ld de, MUSIC_NONE
call PlayMusic
call DelayFrame
pop de
ld a, e
ld [CurMusic], a
call PlayMusic
pop af
pop bc
pop de
pop hl
ret
; 3d2f
Function3d2f:: ; 3d2f
ld a, [$c2c1]
and a
jr z, Function3d47
xor a
ld [CurMusic], a
ld de, MUSIC_NONE
call PlayMusic
call DelayFrame
xor a
ld [$c2c1], a
ret
; 3d47
Function3d47:: ; 3d47
push hl
push de
push bc
push af
ld de, MUSIC_NONE
call PlayMusic
call DelayFrame
ld a, [CurMusic]
ld e, a
ld d, 0
call PlayMusic
pop af
pop bc
pop de
pop hl
ret
; 3d62
Function3d62:: ; 3d62
ld a, [PlayerState]
cp $4
jr z, .asm_3d7b
cp $8
jr z, .asm_3d7b
ld a, [StatusFlags2]
bit 2, a
jr nz, .asm_3d80
.asm_3d74
and a
ret
ld de, $0013
scf
ret
.asm_3d7b
ld de, $0021
scf
ret
.asm_3d80
ld a, [MapGroup]
cp $a
jr nz, .asm_3d74
ld a, [MapNumber]
cp $f
jr z, .asm_3d92
cp $11
jr nz, .asm_3d74
.asm_3d92
ld de, $0058
scf
ret
; 3d97
Function3d97:: ; 3d97
call Function3d62
ret c
call Function2cbd
ret
; 3d9f
Function3d9f:: ; 3d9f
ld a, $20
ld [$c498], a
ld [$c49c], a
ld a, $50
ld [$c499], a
ld a, $58
ld [$c49d], a
xor a
ld [$c49b], a
ld [$c49f], a
ld a, [$c296]
cp $64
jr nc, .asm_3dd5
add $1
daa
ld b, a
swap a
and $f
add $f6
ld [$c49a], a
ld a, b
and $f
add $f6
ld [$c49e], a
ret
.asm_3dd5
ld a, $ff
ld [$c49a], a
ld [$c49e], a
ret
; 3dde
CheckSFX:: ; 3dde
; returns carry if sfx channels are active
ld a, [$c1cc] ; 1
bit 0, a
jr nz, .quit
ld a, [$c1fe] ; 2
bit 0, a
jr nz, .quit
ld a, [$c230] ; 3
bit 0, a
jr nz, .quit
ld a, [$c262] ; 4
bit 0, a
jr nz, .quit
and a
ret
.quit
scf
ret
; 3dfe
Function3dfe:: ; 3dfe
xor a
ld [$c1cc], a
ld [SoundInput], a
ld [rNR10], a
ld [rNR11], a
ld [rNR12], a
ld [rNR13], a
ld [rNR14], a
ret
; 3e10
ChannelsOff:: ; 3e10
; Quickly turn off music channels
xor a
ld [Channel1Flags], a
ld [$c136], a
ld [$c168], a
ld [$c19a], a
ld [SoundInput], a
ret
; 3e21
SFXChannelsOff:: ; 3e21
; Quickly turn off sound effect channels
xor a
ld [$c1cc], a
ld [$c1fe], a
ld [$c230], a
ld [$c262], a
ld [SoundInput], a
ret
; 3e32
Function3e32:: ; 3e32
cp $2
ld [$c988], a
ld a, l
ld [$c986], a
ld a, h
ld [$c987], a
jr nz, .asm_3e4f
ld [$c982], a
ld a, l
ld [$c981], a
ld hl, $c983
ld a, c
ld [hli], a
ld a, b
ld [hl], a
.asm_3e4f
ld hl, $c822
set 6, [hl]
ld a, [hROMBank]
push af
ld a, BANK(Function110030)
ld [$c981], a
rst Bankswitch
jp Function110030
; 3e60
Function3e60:: ; 3e60
ld [$c986], a
ld a, l
ld [$c987], a
ld a, h
ld [$c988], a
pop bc
ld a, b
ld [$c981], a
rst Bankswitch
ld hl, $c822
res 6, [hl]
ld hl, $c987
ld a, [hli]
ld h, [hl]
ld l, a
ld a, [$c986]
ret
; 3e80
Function3e80:: ; 3e80
ld a, [hROMBank]
push af
ld a, BANK(Function1116c5)
ld [$c981], a
rst Bankswitch
call Function1116c5
pop bc
ld a, b
ld [$c981], a
rst Bankswitch
ret
; 3e93
Timer:: ; 3e93
push af
push bc
push de
push hl
ld a, [$ffe9]
and a
jr z, .asm_3ed2
xor a
ld [rTAC], a
; Turn off timer interrupt
ld a, [rIF]
and 1 << VBLANK | 1 << LCD_STAT | 1 << SERIAL | 1 << JOYPAD
ld [rIF], a
ld a, [$c86a]
or a
jr z, .asm_3ed2
ld a, [$c822]
bit 1, a
jr nz, .asm_3eca
ld a, [rSC]
and 1 << rSC_ON
jr nz, .asm_3eca
ld a, [hROMBank]
push af
ld a, BANK(Function1118de)
ld [$c981], a
rst Bankswitch
call Function1118de
pop bc
ld a, b
ld [$c981], a
rst Bankswitch
.asm_3eca
ld a, [rTMA]
ld [rTIMA], a
ld a, 1 << rTAC_ON | rTAC_65536_HZ
ld [rTAC], a
.asm_3ed2
pop hl
pop de
pop bc
pop af
reti
; 3ed7
Function3ed7:: ; 3ed7
ld [$dc02], a
ld a, [hROMBank]
push af
ld a, BANK(Function114243)
rst Bankswitch
call Function114243
pop bc
ld a, b
rst Bankswitch
ld a, [$dc02]
ret
; 3eea
Function3eea:: ; 3eea
push hl
push bc
ld de, $0939
add hl, de
inc b
inc b
inc c
inc c
call Function3f35
pop bc
pop hl
call Function3f47
ret
; 3efd
Function3efd:: ; 3efd
push hl
ld hl, $c590
ld b, $4
ld c, $12
call Function3f0d
pop hl
call PrintTextBoxText
ret
; 3f0d
Function3f0d:: ; 3f0d
push hl
push bc
ld de, $0939
add hl, de
inc b
inc b
inc c
inc c
call Function3f35
pop bc
pop hl
call TextBoxBorder
ret
; 3f20
Function3f20:: ; 3f20
ld hl, AttrMap
ld b, $6
ld c, $14
call Function3f35
ld hl, TileMap
ld b, $4
ld c, $12
call Function3f47
ret
; 3f35
Function3f35:: ; 3f35
ld a, $6
ld de, $0014
.asm_3f3a
push bc
push hl
.asm_3f3c
ld [hli], a
dec c
jr nz, .asm_3f3c
pop hl
add hl, de
pop bc
dec b
jr nz, .asm_3f3a
ret
; 3f47
Function3f47:: ; 3f47
push bc
call Function3f58
pop bc
.asm_3f4c
push bc
call Function3f68
pop bc
dec b
jr nz, .asm_3f4c
call Function3f60
ret
; 3f58
Function3f58:: ; 3f58
ld a, $63
ld d, $62
ld e, $64
jr Function3f6e
Function3f60:: ; 3f60
ld a, $68
ld d, $67
ld e, $69
jr Function3f6e
Function3f68:: ; 3f68
ld a, $7f
ld d, $65
ld e, $66
Function3f6e:: ; 3f6e
push hl
ld [hl], d
inc hl
.asm_3f71
ld [hli], a
dec c
jr nz, .asm_3f71
ld [hl], e
pop hl
ld de, $0014
add hl, de
ret
; 3f7c
Function3f7c:: ; 3f7c
call Function1cfd
call Function1c53
dec b
dec c
call Function3eea
ret
; 3f88
Function3f88:: ; 3f88
ld hl, $d000
ld b, $0
.asm_3f8d
push bc
ld c, $8
.asm_3f90
ld a, [de]
inc de
cpl
ld [hl], $0
inc hl
ld [hli], a
dec c
jr nz, .asm_3f90
pop bc
dec c
jr nz, .asm_3f8d
ret
; 3f9f
Function3f9f:: ; 3f9f
ld hl, $d000
.asm_3fa2
push bc
ld c, $8
.asm_3fa5
ld a, [de]
inc de
inc de
cpl
ld [hl], $0
inc hl
ld [hli], a
dec c
jr nz, .asm_3fa5
pop bc
dec c
jr nz, .asm_3fa2
ret
; 3fb5