pokecrystal-board/engine/pokegear/pokegear.asm

2944 lines
48 KiB
NASM
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

; Pokégear cards
const_def
const POKEGEARCARD_CLOCK ; 0
const POKEGEARCARD_MAP ; 1
const POKEGEARCARD_PHONE ; 2
const POKEGEARCARD_RADIO ; 3
NUM_POKEGEAR_CARDS EQU const_value
PHONE_DISPLAY_HEIGHT EQU 4
; PokegearJumptable.Jumptable indexes
const_def
const POKEGEARSTATE_CLOCKINIT ; 0
const POKEGEARSTATE_CLOCKJOYPAD ; 1
const POKEGEARSTATE_MAPCHECKREGION ; 2
const POKEGEARSTATE_JOHTOMAPINIT ; 3
const POKEGEARSTATE_JOHTOMAPJOYPAD ; 4
const POKEGEARSTATE_KANTOMAPINIT ; 5
const POKEGEARSTATE_KANTOMAPJOYPAD ; 6
const POKEGEARSTATE_PHONEINIT ; 7
const POKEGEARSTATE_PHONEJOYPAD ; 8
const POKEGEARSTATE_MAKEPHONECALL ; 9
const POKEGEARSTATE_FINISHPHONECALL ; a
const POKEGEARSTATE_RADIOINIT ; b
const POKEGEARSTATE_RADIOJOYPAD ; c
PokeGear:
ld hl, wOptions
ld a, [hl]
push af
set NO_TEXT_SCROLL, [hl]
ldh a, [hInMenu]
push af
ld a, $1
ldh [hInMenu], a
ld a, [wVramState]
push af
xor a
ld [wVramState], a
call .InitTilemap
call DelayFrame
.loop
call UpdateTime
call JoyTextDelay
ld a, [wJumptableIndex]
bit 7, a
jr nz, .done
call PokegearJumptable
farcall PlaySpriteAnimations
call DelayFrame
jr .loop
.done
ld de, SFX_READ_TEXT_2
call PlaySFX
call WaitSFX
pop af
ld [wVramState], a
pop af
ldh [hInMenu], a
pop af
ld [wOptions], a
call ClearBGPalettes
xor a ; LOW(vBGMap0)
ldh [hBGMapAddress], a
ld a, HIGH(vBGMap0)
ldh [hBGMapAddress + 1], a
ld a, $90
ldh [hWY], a
call ExitPokegearRadio_HandleMusic
ret
.InitTilemap:
call ClearBGPalettes
call ClearTilemap
call ClearSprites
call DisableLCD
xor a
ldh [hSCY], a
ldh [hSCX], a
ld a, $7
ldh [hWX], a
call Pokegear_LoadGFX
farcall ClearSpriteAnims
call InitPokegearModeIndicatorArrow
ld a, 8
call SkipMusic
ld a, LCDC_DEFAULT
ldh [rLCDC], a
call TownMap_InitCursorAndPlayerIconPositions
xor a
ld [wJumptableIndex], a ; POKEGEARSTATE_CLOCKINIT
ld [wPokegearCard], a ; POKEGEARCARD_CLOCK
ld [wPokegearMapRegion], a ; JOHTO_REGION
ld [wcf66], a
ld [wPokegearPhoneScrollPosition], a
ld [wPokegearPhoneCursorPosition], a
ld [wPokegearPhoneSelectedPerson], a
ld [wPokegearRadioChannelBank], a
ld [wPokegearRadioChannelAddr], a
ld [wPokegearRadioChannelAddr + 1], a
call Pokegear_InitJumptableIndices
call InitPokegearTilemap
ld b, SCGB_POKEGEAR_PALS
call GetSGBLayout
call SetPalettes
ldh a, [hCGB]
and a
ret z
ld a, %11100100
call DmgToCgbObjPal0
ret
Pokegear_LoadGFX:
call ClearVBank1
ld hl, TownMapGFX
ld de, vTiles2
ld a, BANK(TownMapGFX)
call FarDecompress
ld hl, PokegearGFX
ld de, vTiles2 tile $30
ld a, BANK(PokegearGFX)
call FarDecompress
ld hl, PokegearSpritesGFX
ld de, vTiles0
ld a, BANK(PokegearSpritesGFX)
call Decompress
ld a, [wMapGroup]
ld b, a
ld a, [wMapNumber]
ld c, a
call GetWorldMapLocation
cp LANDMARK_FAST_SHIP
jr z, .ssaqua
farcall GetPlayerIcon
push de
ld h, d
ld l, e
ld a, b
; standing sprite
push af
ld de, vTiles0 tile $10
ld bc, 4 tiles
call FarCopyBytes
pop af
pop hl
; walking sprite
ld de, 12 tiles
add hl, de
ld de, vTiles0 tile $14
ld bc, 4 tiles
call FarCopyBytes
ret
.ssaqua
ld hl, FastShipGFX
ld de, vTiles0 tile $10
ld bc, 8 tiles
call CopyBytes
ret
FastShipGFX:
INCBIN "gfx/pokegear/fast_ship.2bpp"
InitPokegearModeIndicatorArrow:
depixel 4, 2, 4, 0
ld a, SPRITE_ANIM_INDEX_POKEGEAR_ARROW
call InitSpriteAnimStruct
ld hl, SPRITEANIMSTRUCT_TILE_ID
add hl, bc
ld [hl], $0
ret
AnimatePokegearModeIndicatorArrow:
ld hl, wPokegearCard
ld e, [hl]
ld d, 0
ld hl, .XCoords
add hl, de
ld a, [hl]
ld hl, SPRITEANIMSTRUCT_XOFFSET
add hl, bc
ld [hl], a
ret
.XCoords:
db $00 ; POKEGEARCARD_CLOCK
db $10 ; POKEGEARCARD_MAP
db $20 ; POKEGEARCARD_PHONE
db $30 ; POKEGEARCARD_RADIO
TownMap_GetCurrentLandmark:
ld a, [wMapGroup]
ld b, a
ld a, [wMapNumber]
ld c, a
call GetWorldMapLocation
cp LANDMARK_SPECIAL
ret nz
ld a, [wBackupMapGroup]
ld b, a
ld a, [wBackupMapNumber]
ld c, a
call GetWorldMapLocation
ret
TownMap_InitCursorAndPlayerIconPositions:
ld a, [wMapGroup]
ld b, a
ld a, [wMapNumber]
ld c, a
call GetWorldMapLocation
cp LANDMARK_FAST_SHIP
jr z, .FastShip
cp LANDMARK_SPECIAL
jr nz, .LoadLandmark
ld a, [wBackupMapGroup]
ld b, a
ld a, [wBackupMapNumber]
ld c, a
call GetWorldMapLocation
.LoadLandmark:
ld [wPokegearMapPlayerIconLandmark], a
ld [wPokegearMapCursorLandmark], a
ret
.FastShip:
ld [wPokegearMapPlayerIconLandmark], a
ld a, LANDMARK_NEW_BARK_TOWN
ld [wPokegearMapCursorLandmark], a
ret
Pokegear_InitJumptableIndices:
ld a, POKEGEARSTATE_CLOCKINIT
ld [wJumptableIndex], a
xor a ; POKEGEARCARD_CLOCK
ld [wPokegearCard], a
ret
InitPokegearTilemap:
xor a
ldh [hBGMapMode], a
hlcoord 0, 0
ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
ld a, $4f
call ByteFill
ld a, [wPokegearCard]
maskbits NUM_POKEGEAR_CARDS
add a
ld e, a
ld d, 0
ld hl, .Jumptable
add hl, de
ld a, [hli]
ld h, [hl]
ld l, a
ld de, .return_from_jumptable
push de
jp hl
.return_from_jumptable
call Pokegear_FinishTilemap
farcall TownMapPals
ld a, [wPokegearMapRegion]
and a
jr nz, .kanto_0
xor a ; LOW(vBGMap0)
ldh [hBGMapAddress], a
ld a, HIGH(vBGMap0)
ldh [hBGMapAddress + 1], a
call .UpdateBGMap
ld a, $90
jr .finish
.kanto_0
xor a ; LOW(vBGMap1)
ldh [hBGMapAddress], a
ld a, HIGH(vBGMap1)
ldh [hBGMapAddress + 1], a
call .UpdateBGMap
xor a
.finish
ldh [hWY], a
; swap region maps
ld a, [wPokegearMapRegion]
maskbits NUM_REGIONS
xor 1
ld [wPokegearMapRegion], a
ret
.UpdateBGMap:
ldh a, [hCGB]
and a
jr z, .dmg
ld a, $2
ldh [hBGMapMode], a
ld c, 3
call DelayFrames
.dmg
call WaitBGMap
ret
.Jumptable:
; entries correspond to POKEGEARCARD_* constants
dw .Clock
dw .Map
dw .Phone
dw .Radio
.Clock:
ld de, ClockTilemapRLE
call Pokegear_LoadTilemapRLE
hlcoord 12, 1
ld de, .switch
call PlaceString
hlcoord 0, 12
lb bc, 4, 18
call Textbox
call Pokegear_UpdateClock
ret
.switch
db " SWITCH▶@"
.Map:
ld a, [wPokegearMapPlayerIconLandmark]
cp LANDMARK_FAST_SHIP
jr z, .johto
cp KANTO_LANDMARK
jr nc, .kanto
.johto
ld e, 0
jr .ok
.kanto
ld e, 1
.ok
farcall PokegearMap
ld a, $07
ld bc, SCREEN_WIDTH - 2
hlcoord 1, 2
call ByteFill
hlcoord 0, 2
ld [hl], $06
hlcoord 19, 2
ld [hl], $17
ld a, [wPokegearMapCursorLandmark]
call PokegearMap_UpdateLandmarkName
ret
.Radio:
ld de, RadioTilemapRLE
call Pokegear_LoadTilemapRLE
hlcoord 0, 12
lb bc, 4, 18
call Textbox
ret
.Phone:
ld de, PhoneTilemapRLE
call Pokegear_LoadTilemapRLE
hlcoord 0, 12
lb bc, 4, 18
call Textbox
call .PlacePhoneBars
call PokegearPhone_UpdateDisplayList
ret
.PlacePhoneBars:
hlcoord 17, 1
ld a, $3c
ld [hli], a
inc a
ld [hl], a
hlcoord 17, 2
inc a
ld [hli], a
call GetMapPhoneService
and a
ret nz
hlcoord 18, 2
ld [hl], $3f
ret
Pokegear_FinishTilemap:
hlcoord 0, 0
ld bc, $8
ld a, $4f
call ByteFill
hlcoord 0, 1
ld bc, $8
ld a, $4f
call ByteFill
ld de, wPokegearFlags
ld a, [de]
bit POKEGEAR_MAP_CARD_F, a
call nz, .PlaceMapIcon
ld a, [de]
bit POKEGEAR_PHONE_CARD_F, a
call nz, .PlacePhoneIcon
ld a, [de]
bit POKEGEAR_RADIO_CARD_F, a
call nz, .PlaceRadioIcon
hlcoord 0, 0
ld a, $46
call .PlacePokegearCardIcon
ret
.PlaceMapIcon:
hlcoord 2, 0
ld a, $40
jr .PlacePokegearCardIcon
.PlacePhoneIcon:
hlcoord 4, 0
ld a, $44
jr .PlacePokegearCardIcon
.PlaceRadioIcon:
hlcoord 6, 0
ld a, $42
.PlacePokegearCardIcon:
ld [hli], a
inc a
ld [hld], a
ld bc, $14
add hl, bc
add $f
ld [hli], a
inc a
ld [hld], a
ret
PokegearJumptable:
ld a, [wJumptableIndex]
ld e, a
ld d, 0
ld hl, .Jumptable
add hl, de
add hl, de
ld a, [hli]
ld h, [hl]
ld l, a
jp hl
.Jumptable:
; entries correspond to POKEGEARSTATE_* constants
dw PokegearClock_Init
dw PokegearClock_Joypad
dw PokegearMap_CheckRegion
dw PokegearMap_Init
dw PokegearMap_JohtoMap
dw PokegearMap_Init
dw PokegearMap_KantoMap
dw PokegearPhone_Init
dw PokegearPhone_Joypad
dw PokegearPhone_MakePhoneCall
dw PokegearPhone_FinishPhoneCall
dw PokegearRadio_Init
dw PokegearRadio_Joypad
PokegearClock_Init:
call InitPokegearTilemap
ld hl, PokegearPressButtonText
call PrintText
ld hl, wJumptableIndex
inc [hl]
call ExitPokegearRadio_HandleMusic
ret
PokegearClock_Joypad:
call .UpdateClock
ld hl, hJoyLast
ld a, [hl]
and A_BUTTON | B_BUTTON | START | SELECT
jr nz, .quit
ld a, [hl]
and D_RIGHT
ret z
ld a, [wPokegearFlags]
bit POKEGEAR_MAP_CARD_F, a
jr z, .no_map_card
ld c, POKEGEARSTATE_MAPCHECKREGION
ld b, POKEGEARCARD_MAP
jr .done
.no_map_card
ld a, [wPokegearFlags]
bit POKEGEAR_PHONE_CARD_F, a
jr z, .no_phone_card
ld c, POKEGEARSTATE_PHONEINIT
ld b, POKEGEARCARD_PHONE
jr .done
.no_phone_card
ld a, [wPokegearFlags]
bit POKEGEAR_RADIO_CARD_F, a
ret z
ld c, POKEGEARSTATE_RADIOINIT
ld b, POKEGEARCARD_RADIO
.done
call Pokegear_SwitchPage
ret
.quit
ld hl, wJumptableIndex
set 7, [hl]
ret
.UpdateClock:
xor a
ldh [hBGMapMode], a
call Pokegear_UpdateClock
ld a, $1
ldh [hBGMapMode], a
ret
Pokegear_UpdateClock:
hlcoord 3, 5
lb bc, 5, 14
call ClearBox
ldh a, [hHours]
ld b, a
ldh a, [hMinutes]
ld c, a
decoord 6, 8
farcall PrintHoursMins
ld hl, .GearTodayText
bccoord 6, 6
call PlaceHLTextAtBC
ret
db "ごぜん@"
db "ごご@"
.GearTodayText:
text_far _GearTodayText
text_end
PokegearMap_CheckRegion:
ld a, [wPokegearMapPlayerIconLandmark]
cp LANDMARK_FAST_SHIP
jr z, .johto
cp KANTO_LANDMARK
jr nc, .kanto
.johto
ld a, POKEGEARSTATE_JOHTOMAPINIT
jr .done
ret
.kanto
ld a, POKEGEARSTATE_KANTOMAPINIT
.done
ld [wJumptableIndex], a
call ExitPokegearRadio_HandleMusic
ret
PokegearMap_Init:
call InitPokegearTilemap
ld a, [wPokegearMapPlayerIconLandmark]
call PokegearMap_InitPlayerIcon
ld a, [wPokegearMapCursorLandmark]
call PokegearMap_InitCursor
ld a, c
ld [wPokegearMapCursorObjectPointer], a
ld a, b
ld [wPokegearMapCursorObjectPointer + 1], a
ld hl, wJumptableIndex
inc [hl]
ret
PokegearMap_KantoMap:
call TownMap_GetKantoLandmarkLimits
jr PokegearMap_ContinueMap
PokegearMap_JohtoMap:
ld d, LANDMARK_SILVER_CAVE
ld e, LANDMARK_NEW_BARK_TOWN
PokegearMap_ContinueMap:
ld hl, hJoyLast
ld a, [hl]
and B_BUTTON
jr nz, .cancel
ld a, [hl]
and D_RIGHT
jr nz, .right
ld a, [hl]
and D_LEFT
jr nz, .left
call .DPad
ret
.right
ld a, [wPokegearFlags]
bit POKEGEAR_PHONE_CARD_F, a
jr z, .no_phone
ld c, POKEGEARSTATE_PHONEINIT
ld b, POKEGEARCARD_PHONE
jr .done
.no_phone
ld a, [wPokegearFlags]
bit POKEGEAR_RADIO_CARD_F, a
ret z
ld c, POKEGEARSTATE_RADIOINIT
ld b, POKEGEARCARD_RADIO
jr .done
.left
ld c, POKEGEARSTATE_CLOCKINIT
ld b, POKEGEARCARD_CLOCK
.done
call Pokegear_SwitchPage
ret
.cancel
ld hl, wJumptableIndex
set 7, [hl]
ret
.DPad:
ld hl, hJoyLast
ld a, [hl]
and D_UP
jr nz, .up
ld a, [hl]
and D_DOWN
jr nz, .down
ret
.up
ld hl, wPokegearMapCursorLandmark
ld a, [hl]
cp d
jr c, .wrap_around_up
ld a, e
dec a
ld [hl], a
.wrap_around_up
inc [hl]
jr .done_dpad
.down
ld hl, wPokegearMapCursorLandmark
ld a, [hl]
cp e
jr nz, .wrap_around_down
ld a, d
inc a
ld [hl], a
.wrap_around_down
dec [hl]
.done_dpad
ld a, [wPokegearMapCursorLandmark]
call PokegearMap_UpdateLandmarkName
ld a, [wPokegearMapCursorObjectPointer]
ld c, a
ld a, [wPokegearMapCursorObjectPointer + 1]
ld b, a
ld a, [wPokegearMapCursorLandmark]
call PokegearMap_UpdateCursorPosition
ret
PokegearMap_InitPlayerIcon:
push af
depixel 0, 0
ld b, SPRITE_ANIM_INDEX_RED_WALK
ld a, [wPlayerGender]
bit PLAYERGENDER_FEMALE_F, a
jr z, .got_gender
ld b, SPRITE_ANIM_INDEX_BLUE_WALK
.got_gender
ld a, b
call InitSpriteAnimStruct
ld hl, SPRITEANIMSTRUCT_TILE_ID
add hl, bc
ld [hl], $10
pop af
ld e, a
push bc
farcall GetLandmarkCoords
pop bc
ld hl, SPRITEANIMSTRUCT_XCOORD
add hl, bc
ld [hl], e
ld hl, SPRITEANIMSTRUCT_YCOORD
add hl, bc
ld [hl], d
ret
PokegearMap_InitCursor:
push af
depixel 0, 0
ld a, SPRITE_ANIM_INDEX_POKEGEAR_ARROW
call InitSpriteAnimStruct
ld hl, SPRITEANIMSTRUCT_TILE_ID
add hl, bc
ld [hl], $04
ld hl, SPRITEANIMSTRUCT_ANIM_SEQ_ID
add hl, bc
ld [hl], SPRITE_ANIM_SEQ_NULL
pop af
push bc
call PokegearMap_UpdateCursorPosition
pop bc
ret
PokegearMap_UpdateLandmarkName:
push af
hlcoord 8, 0
lb bc, 2, 12
call ClearBox
pop af
ld e, a
push de
farcall GetLandmarkName
pop de
farcall TownMap_ConvertLineBreakCharacters
hlcoord 8, 0
ld [hl], $34
ret
PokegearMap_UpdateCursorPosition:
push bc
ld e, a
farcall GetLandmarkCoords
pop bc
ld hl, SPRITEANIMSTRUCT_XCOORD
add hl, bc
ld [hl], e
ld hl, SPRITEANIMSTRUCT_YCOORD
add hl, bc
ld [hl], d
ret
TownMap_GetKantoLandmarkLimits:
ld a, [wStatusFlags]
bit STATUSFLAGS_HALL_OF_FAME_F, a
jr z, .not_hof
ld d, LANDMARK_ROUTE_28
ld e, LANDMARK_PALLET_TOWN
ret
.not_hof
ld d, LANDMARK_ROUTE_28
ld e, LANDMARK_VICTORY_ROAD
ret
PokegearRadio_Init:
call InitPokegearTilemap
depixel 4, 10, 4, 4
ld a, SPRITE_ANIM_INDEX_RADIO_TUNING_KNOB
call InitSpriteAnimStruct
ld hl, SPRITEANIMSTRUCT_TILE_ID
add hl, bc
ld [hl], $08
call _UpdateRadioStation
ld hl, wJumptableIndex
inc [hl]
ret
PokegearRadio_Joypad:
ld hl, hJoyLast
ld a, [hl]
and B_BUTTON
jr nz, .cancel
ld a, [hl]
and D_LEFT
jr nz, .left
ld a, [wPokegearRadioChannelAddr]
ld l, a
ld a, [wPokegearRadioChannelAddr + 1]
ld h, a
ld a, [wPokegearRadioChannelBank]
and a
ret z
rst FarCall
ret
.left
ld a, [wPokegearFlags]
bit POKEGEAR_PHONE_CARD_F, a
jr z, .no_phone
ld c, POKEGEARSTATE_PHONEINIT
ld b, POKEGEARCARD_PHONE
jr .switch_page
.no_phone
ld a, [wPokegearFlags]
bit POKEGEAR_MAP_CARD_F, a
jr z, .no_map
ld c, POKEGEARSTATE_MAPCHECKREGION
ld b, POKEGEARCARD_MAP
jr .switch_page
.no_map
ld c, POKEGEARSTATE_CLOCKINIT
ld b, POKEGEARCARD_CLOCK
.switch_page
call Pokegear_SwitchPage
ret
.cancel
ld hl, wJumptableIndex
set 7, [hl]
ret
PokegearPhone_Init:
ld hl, wJumptableIndex
inc [hl]
xor a
ld [wPokegearPhoneScrollPosition], a
ld [wPokegearPhoneCursorPosition], a
ld [wPokegearPhoneSelectedPerson], a
call InitPokegearTilemap
call ExitPokegearRadio_HandleMusic
ld hl, PokegearAskWhoCallText
call PrintText
ret
PokegearPhone_Joypad:
ld hl, hJoyPressed
ld a, [hl]
and B_BUTTON
jr nz, .b
ld a, [hl]
and A_BUTTON
jr nz, .a
ld hl, hJoyLast
ld a, [hl]
and D_LEFT
jr nz, .left
ld a, [hl]
and D_RIGHT
jr nz, .right
call PokegearPhone_GetDPad
ret
.left
ld a, [wPokegearFlags]
bit POKEGEAR_MAP_CARD_F, a
jr z, .no_map
ld c, POKEGEARSTATE_MAPCHECKREGION
ld b, POKEGEARCARD_MAP
jr .switch_page
.no_map
ld c, POKEGEARSTATE_CLOCKINIT
ld b, POKEGEARCARD_CLOCK
jr .switch_page
.right
ld a, [wPokegearFlags]
bit POKEGEAR_RADIO_CARD_F, a
ret z
ld c, POKEGEARSTATE_RADIOINIT
ld b, POKEGEARCARD_RADIO
.switch_page
call Pokegear_SwitchPage
ret
.b
ld hl, wJumptableIndex
set 7, [hl]
ret
.a
ld hl, wPhoneList
ld a, [wPokegearPhoneScrollPosition]
ld e, a
ld d, 0
add hl, de
ld a, [wPokegearPhoneCursorPosition]
ld e, a
ld d, 0
add hl, de
ld a, [hl]
and a
ret z
ld [wPokegearPhoneSelectedPerson], a
hlcoord 1, 4
ld a, [wPokegearPhoneCursorPosition]
ld bc, SCREEN_WIDTH * 2
call AddNTimes
ld [hl], "▷"
call PokegearPhoneContactSubmenu
jr c, .quit_submenu
ld hl, wJumptableIndex
inc [hl]
ret
.quit_submenu
ld a, POKEGEARSTATE_PHONEJOYPAD
ld [wJumptableIndex], a
ret
PokegearPhone_MakePhoneCall:
call GetMapPhoneService
and a
jr nz, .no_service
ld hl, wOptions
res NO_TEXT_SCROLL, [hl]
xor a
ldh [hInMenu], a
ld de, SFX_CALL
call PlaySFX
ld hl, .GearEllipseText
call PrintText
call WaitSFX
ld de, SFX_CALL
call PlaySFX
ld hl, .GearEllipseText
call PrintText
call WaitSFX
ld a, [wPokegearPhoneSelectedPerson]
ld b, a
call Function90199
ld c, 10
call DelayFrames
ld hl, wOptions
set NO_TEXT_SCROLL, [hl]
ld a, $1
ldh [hInMenu], a
call PokegearPhone_UpdateCursor
ld hl, wJumptableIndex
inc [hl]
ret
.no_service
farcall Phone_NoSignal
ld hl, .GearOutOfServiceText
call PrintText
ld a, POKEGEARSTATE_PHONEJOYPAD
ld [wJumptableIndex], a
ld hl, PokegearAskWhoCallText
call PrintText
ret
.GearEllipseText:
text_far _GearEllipseText
text_end
.GearOutOfServiceText:
text_far _GearOutOfServiceText
text_end
PokegearPhone_FinishPhoneCall:
ldh a, [hJoyPressed]
and A_BUTTON | B_BUTTON
ret z
farcall HangUp
ld a, POKEGEARSTATE_PHONEJOYPAD
ld [wJumptableIndex], a
ld hl, PokegearAskWhoCallText
call PrintText
ret
PokegearPhone_GetDPad:
ld hl, hJoyLast
ld a, [hl]
and D_UP
jr nz, .up
ld a, [hl]
and D_DOWN
jr nz, .down
ret
.up
ld hl, wPokegearPhoneCursorPosition
ld a, [hl]
and a
jr z, .scroll_page_up
dec [hl]
jr .done_joypad_same_page
.scroll_page_up
ld hl, wPokegearPhoneScrollPosition
ld a, [hl]
and a
ret z
dec [hl]
jr .done_joypad_update_page
.down
ld hl, wPokegearPhoneCursorPosition
ld a, [hl]
cp PHONE_DISPLAY_HEIGHT - 1
jr nc, .scroll_page_down
inc [hl]
jr .done_joypad_same_page
.scroll_page_down
ld hl, wPokegearPhoneScrollPosition
ld a, [hl]
cp CONTACT_LIST_SIZE - PHONE_DISPLAY_HEIGHT
ret nc
inc [hl]
jr .done_joypad_update_page
.done_joypad_same_page
xor a
ldh [hBGMapMode], a
call PokegearPhone_UpdateCursor
call WaitBGMap
ret
.done_joypad_update_page
xor a
ldh [hBGMapMode], a
call PokegearPhone_UpdateDisplayList
call WaitBGMap
ret
PokegearPhone_UpdateCursor:
ld a, " "
x = 4
rept PHONE_DISPLAY_HEIGHT
hlcoord 1, x
ld [hl], a
x = x + 2
endr
hlcoord 1, 4
ld a, [wPokegearPhoneCursorPosition]
ld bc, 2 * SCREEN_WIDTH
call AddNTimes
ld [hl], "▶"
ret
PokegearPhone_UpdateDisplayList:
hlcoord 1, 3
ld b, PHONE_DISPLAY_HEIGHT * 2 + 1
ld a, " "
.row
ld c, SCREEN_WIDTH - 2
.col
ld [hli], a
dec c
jr nz, .col
inc hl
inc hl
dec b
jr nz, .row
ld a, [wPokegearPhoneScrollPosition]
ld e, a
ld d, 0
ld hl, wPhoneList
add hl, de
xor a
ld [wPokegearPhoneLoadNameBuffer], a
.loop
ld a, [hli]
push hl
push af
hlcoord 2, 4
ld a, [wPokegearPhoneLoadNameBuffer]
ld bc, 2 * SCREEN_WIDTH
call AddNTimes
ld d, h
ld e, l
pop af
ld b, a
call Function90380
pop hl
ld a, [wPokegearPhoneLoadNameBuffer]
inc a
ld [wPokegearPhoneLoadNameBuffer], a
cp PHONE_DISPLAY_HEIGHT
jr c, .loop
call PokegearPhone_UpdateCursor
ret
PokegearPhone_DeletePhoneNumber:
ld hl, wPhoneList
ld a, [wPokegearPhoneScrollPosition]
ld e, a
ld d, 0
add hl, de
ld a, [wPokegearPhoneCursorPosition]
ld e, a
ld d, 0
add hl, de
ld [hl], 0
ld hl, wPhoneList
ld c, CONTACT_LIST_SIZE
.loop
ld a, [hli]
and a
jr nz, .skip
ld a, [hld]
ld [hli], a
ld [hl], 0
.skip
dec c
jr nz, .loop
ret
PokegearPhoneContactSubmenu:
ld hl, wPhoneList
ld a, [wPokegearPhoneScrollPosition]
ld e, a
ld d, 0
add hl, de
ld a, [wPokegearPhoneCursorPosition]
ld e, a
ld d, 0
add hl, de
ld c, [hl]
farcall CheckCanDeletePhoneNumber
ld a, c
and a
jr z, .cant_delete
ld hl, .CallDeleteCancelJumptable
ld de, .CallDeleteCancelStrings
jr .got_menu_data
.cant_delete
ld hl, .CallCancelJumptable
ld de, .CallCancelStrings
.got_menu_data
xor a
ldh [hBGMapMode], a
push hl
push de
ld a, [de]
ld l, a
inc de
ld a, [de]
ld h, a
inc de
push hl
bccoord -1, -2, 0
add hl, bc
ld a, [de]
inc de
sla a
ld b, a
ld c, 8
push de
call Textbox
pop de
pop hl
inc hl
call PlaceString
pop de
xor a
ld [wPokegearPhoneSubmenuCursor], a
call .UpdateCursor
call WaitBGMap
.loop
push de
call JoyTextDelay
pop de
ld hl, hJoyPressed
ld a, [hl]
and D_UP
jr nz, .d_up
ld a, [hl]
and D_DOWN
jr nz, .d_down
ld a, [hl]
and A_BUTTON | B_BUTTON
jr nz, .a_b
call DelayFrame
jr .loop
.d_up
ld hl, wPokegearPhoneSubmenuCursor
ld a, [hl]
and a
jr z, .loop
dec [hl]
call .UpdateCursor
jr .loop
.d_down
ld hl, 2
add hl, de
ld a, [wPokegearPhoneSubmenuCursor]
inc a
cp [hl]
jr nc, .loop
ld [wPokegearPhoneSubmenuCursor], a
call .UpdateCursor
jr .loop
.a_b
xor a
ldh [hBGMapMode], a
call PokegearPhone_UpdateDisplayList
ld a, $1
ldh [hBGMapMode], a
pop hl
ldh a, [hJoyPressed]
and B_BUTTON
jr nz, .Cancel
ld a, [wPokegearPhoneSubmenuCursor]
ld e, a
ld d, 0
add hl, de
add hl, de
ld a, [hli]
ld h, [hl]
ld l, a
jp hl
.Cancel:
ld hl, PokegearAskWhoCallText
call PrintText
scf
ret
.Delete:
ld hl, PokegearAskDeleteText
call MenuTextbox
call YesNoBox
call ExitMenu
jr c, .CancelDelete
call PokegearPhone_DeletePhoneNumber
xor a
ldh [hBGMapMode], a
call PokegearPhone_UpdateDisplayList
ld hl, PokegearAskWhoCallText
call PrintText
call WaitBGMap
.CancelDelete:
scf
ret
.Call:
and a
ret
.UpdateCursor:
push de
ld a, [de]
inc de
ld l, a
ld a, [de]
inc de
ld h, a
ld a, [de]
ld c, a
push hl
ld a, " "
ld de, SCREEN_WIDTH * 2
.clear_column
ld [hl], a
add hl, de
dec c
jr nz, .clear_column
pop hl
ld a, [wPokegearPhoneSubmenuCursor]
ld bc, SCREEN_WIDTH * 2
call AddNTimes
ld [hl], "▶"
pop de
ret
.CallDeleteCancelStrings:
dwcoord 10, 6
db 3
db "CALL"
next "DELETE"
next "CANCEL"
db "@"
.CallDeleteCancelJumptable:
dw .Call
dw .Delete
dw .Cancel
.CallCancelStrings:
dwcoord 10, 8
db 2
db "CALL"
next "CANCEL"
db "@"
.CallCancelJumptable:
dw .Call
dw .Cancel
; unused
ldh a, [hHours]
cp 12
jr c, .am
sub 12
ld [wTempByteValue], a
scf
ret
.am
ld [wTempByteValue], a
and a
ret
Pokegear_SwitchPage:
ld de, SFX_READ_TEXT_2
call PlaySFX
ld a, c
ld [wJumptableIndex], a
ld a, b
ld [wPokegearCard], a
call DeleteSpriteAnimStruct2ToEnd
ret
ExitPokegearRadio_HandleMusic:
ld a, [wPokegearRadioMusicPlaying]
cp RESTART_MAP_MUSIC
jr z, .restart_map_music
cp ENTER_MAP_MUSIC
call z, PlayMapMusicBike
xor a
ld [wPokegearRadioMusicPlaying], a
ret
.restart_map_music
call RestartMapMusic
xor a
ld [wPokegearRadioMusicPlaying], a
ret
DeleteSpriteAnimStruct2ToEnd:
ld hl, wSpriteAnim2
ld bc, wSpriteAnimationStructsEnd - wSpriteAnim2
xor a
call ByteFill
ld a, 2
ld [wSpriteAnimCount], a
ret
Pokegear_LoadTilemapRLE:
; Format: repeat count, tile ID
; Terminated with -1
hlcoord 0, 0
.loop
ld a, [de]
cp -1
ret z
ld b, a
inc de
ld a, [de]
ld c, a
inc de
ld a, b
.load
ld [hli], a
dec c
jr nz, .load
jr .loop
PokegearAskWhoCallText:
text_far _PokegearAskWhoCallText
text_end
PokegearPressButtonText:
text_far _PokegearPressButtonText
text_end
PokegearAskDeleteText:
text_far _PokegearAskDeleteText
text_end
PokegearSpritesGFX:
INCBIN "gfx/pokegear/pokegear_sprites.2bpp.lz"
RadioTilemapRLE:
INCBIN "gfx/pokegear/radio.tilemap.rle"
PhoneTilemapRLE:
INCBIN "gfx/pokegear/phone.tilemap.rle"
ClockTilemapRLE:
INCBIN "gfx/pokegear/clock.tilemap.rle"
_UpdateRadioStation:
jr UpdateRadioStation
; called from engine/sprite_anims.asm
AnimateTuningKnob:
push bc
call .TuningKnob
pop bc
ld a, [wRadioTuningKnob]
ld hl, SPRITEANIMSTRUCT_XOFFSET
add hl, bc
ld [hl], a
ret
.TuningKnob:
ld hl, hJoyLast
ld a, [hl]
and D_DOWN
jr nz, .down
ld a, [hl]
and D_UP
jr nz, .up
ret
.down
ld hl, wRadioTuningKnob
ld a, [hl]
and a
ret z
dec [hl]
dec [hl]
jr .update
.up
ld hl, wRadioTuningKnob
ld a, [hl]
cp 80
ret nc
inc [hl]
inc [hl]
.update
UpdateRadioStation:
ld hl, wRadioTuningKnob
ld d, [hl]
ld hl, RadioChannels
.loop
ld a, [hli]
cp -1
jr z, .nostation
cp d
jr z, .foundstation
inc hl
inc hl
jr .loop
.nostation
call NoRadioStation
ret
.foundstation
ld a, [hli]
ld h, [hl]
ld l, a
ld de, .returnafterstation
push de
jp hl
.returnafterstation
ld a, [wPokegearRadioChannelBank]
and a
ret z
xor a
ldh [hBGMapMode], a
hlcoord 2, 9
call PlaceString
ld a, $1
ldh [hBGMapMode], a
ret
; unused
ld [wPokegearRadioChannelBank], a
ld a, [hli]
ld [wPokegearRadioChannelAddr], a
ld a, [hli]
ld [wPokegearRadioChannelAddr + 1], a
ret
RadioChannels:
; entries correspond to constants/radio_constants.asm
; frequency value given here = 4 × ingame_frequency 2
dbw 16, .PKMNTalkAndPokedexShow ; 04.5
dbw 28, .PokemonMusic ; 07.5
dbw 32, .LuckyChannel ; 08.5
dbw 40, .BuenasPassword ; 10.5
dbw 52, .RuinsOfAlphRadio ; 13.5
dbw 64, .PlacesAndPeople ; 16.5
dbw 72, .LetsAllSing ; 18.5
dbw 78, .PokeFluteRadio ; 20.0
dbw 80, .EvolutionRadio ; 20.5
db -1
.PKMNTalkAndPokedexShow:
; Pokédex Show in the morning
; Oak's Pokémon Talk in the afternoon and evening
call .InJohto
jr nc, .NoSignal
ld a, [wTimeOfDay]
and a
jp z, LoadStation_PokedexShow
jp LoadStation_OaksPokemonTalk
.PokemonMusic:
call .InJohto
jr nc, .NoSignal
jp LoadStation_PokemonMusic
.LuckyChannel:
call .InJohto
jr nc, .NoSignal
jp LoadStation_LuckyChannel
.BuenasPassword:
call .InJohto
jr nc, .NoSignal
jp LoadStation_BuenasPassword
.RuinsOfAlphRadio:
ld a, [wPokegearMapPlayerIconLandmark]
cp LANDMARK_RUINS_OF_ALPH
jr nz, .NoSignal
jp LoadStation_UnownRadio
.PlacesAndPeople:
call .InJohto
jr c, .NoSignal
ld a, [wPokegearFlags]
bit POKEGEAR_EXPN_CARD_F, a
jr z, .NoSignal
jp LoadStation_PlacesAndPeople
.LetsAllSing:
call .InJohto
jr c, .NoSignal
ld a, [wPokegearFlags]
bit POKEGEAR_EXPN_CARD_F, a
jr z, .NoSignal
jp LoadStation_LetsAllSing
.PokeFluteRadio:
call .InJohto
jr c, .NoSignal
ld a, [wPokegearFlags]
bit POKEGEAR_EXPN_CARD_F, a
jr z, .NoSignal
jp LoadStation_PokeFluteRadio
.EvolutionRadio:
; This station airs in the Lake of Rage area when Team Rocket is still in Mahogany.
ld a, [wStatusFlags]
bit STATUSFLAGS_ROCKET_SIGNAL_F, a
jr z, .NoSignal
ld a, [wPokegearMapPlayerIconLandmark]
cp LANDMARK_MAHOGANY_TOWN
jr z, .ok
cp LANDMARK_ROUTE_43
jr z, .ok
cp LANDMARK_LAKE_OF_RAGE
jr nz, .NoSignal
.ok
jp LoadStation_EvolutionRadio
.NoSignal:
call NoRadioStation
ret
.InJohto:
; if in Johto or on the S.S. Aqua, set carry
; otherwise clear carry
ld a, [wPokegearMapPlayerIconLandmark]
cp LANDMARK_FAST_SHIP
jr z, .johto
cp KANTO_LANDMARK
jr c, .johto
.kanto
and a
ret
.johto
scf
ret
LoadStation_OaksPokemonTalk:
xor a ; OAKS_POKEMON_TALK
ld [wCurRadioLine], a
ld [wNumRadioLinesPrinted], a
ld a, BANK(PlayRadioShow)
ld hl, PlayRadioShow
call Radio_BackUpFarCallParams
ld de, OaksPKMNTalkName
ret
LoadStation_PokedexShow:
ld a, POKEDEX_SHOW
ld [wCurRadioLine], a
xor a
ld [wNumRadioLinesPrinted], a
ld a, BANK(PlayRadioShow)
ld hl, PlayRadioShow
call Radio_BackUpFarCallParams
ld de, PokedexShowName
ret
LoadStation_PokemonMusic:
ld a, POKEMON_MUSIC
ld [wCurRadioLine], a
xor a
ld [wNumRadioLinesPrinted], a
ld a, BANK(PlayRadioShow)
ld hl, PlayRadioShow
call Radio_BackUpFarCallParams
ld de, PokemonMusicName
ret
LoadStation_LuckyChannel:
ld a, LUCKY_CHANNEL
ld [wCurRadioLine], a
xor a
ld [wNumRadioLinesPrinted], a
ld a, BANK(PlayRadioShow)
ld hl, PlayRadioShow
call Radio_BackUpFarCallParams
ld de, LuckyChannelName
ret
LoadStation_BuenasPassword:
ld a, BUENAS_PASSWORD
ld [wCurRadioLine], a
xor a
ld [wNumRadioLinesPrinted], a
ld a, BANK(PlayRadioShow)
ld hl, PlayRadioShow
call Radio_BackUpFarCallParams
ld de, NotBuenasPasswordName
ld a, [wStatusFlags2]
bit STATUSFLAGS2_ROCKETS_IN_RADIO_TOWER_F, a
ret z
ld de, BuenasPasswordName
ret
BuenasPasswordName: db "BUENA'S PASSWORD@"
NotBuenasPasswordName: db "@"
LoadStation_UnownRadio:
ld a, UNOWN_RADIO
ld [wCurRadioLine], a
xor a
ld [wNumRadioLinesPrinted], a
ld a, BANK(PlayRadioShow)
ld hl, PlayRadioShow
call Radio_BackUpFarCallParams
ld de, UnownStationName
ret
LoadStation_PlacesAndPeople:
ld a, PLACES_AND_PEOPLE
ld [wCurRadioLine], a
xor a
ld [wNumRadioLinesPrinted], a
ld a, BANK(PlayRadioShow)
ld hl, PlayRadioShow
call Radio_BackUpFarCallParams
ld de, PlacesAndPeopleName
ret
LoadStation_LetsAllSing:
ld a, LETS_ALL_SING
ld [wCurRadioLine], a
xor a
ld [wNumRadioLinesPrinted], a
ld a, BANK(PlayRadioShow)
ld hl, PlayRadioShow
call Radio_BackUpFarCallParams
ld de, LetsAllSingName
ret
LoadStation_RocketRadio:
ld a, ROCKET_RADIO
ld [wCurRadioLine], a
xor a
ld [wNumRadioLinesPrinted], a
ld a, BANK(PlayRadioShow)
ld hl, PlayRadioShow
call Radio_BackUpFarCallParams
ld de, LetsAllSingName
ret
LoadStation_PokeFluteRadio:
ld a, POKE_FLUTE_RADIO
ld [wCurRadioLine], a
xor a
ld [wNumRadioLinesPrinted], a
ld a, BANK(PlayRadioShow)
ld hl, PlayRadioShow
call Radio_BackUpFarCallParams
ld de, PokeFluteStationName
ret
LoadStation_EvolutionRadio:
ld a, EVOLUTION_RADIO
ld [wCurRadioLine], a
xor a
ld [wNumRadioLinesPrinted], a
ld a, BANK(PlayRadioShow)
ld hl, PlayRadioShow
call Radio_BackUpFarCallParams
ld de, UnownStationName
ret
DummyLoadStation: ; unreferenced
ret
RadioMusicRestartDE:
push de
ld a, e
ld [wPokegearRadioMusicPlaying], a
ld de, MUSIC_NONE
call PlayMusic
pop de
ld a, e
ld [wMapMusic], a
call PlayMusic
ret
RadioMusicRestartPokemonChannel:
push de
ld a, RESTART_MAP_MUSIC
ld [wPokegearRadioMusicPlaying], a
ld de, MUSIC_NONE
call PlayMusic
pop de
ld de, MUSIC_POKEMON_CHANNEL
call PlayMusic
ret
Radio_BackUpFarCallParams:
ld [wPokegearRadioChannelBank], a
ld a, l
ld [wPokegearRadioChannelAddr], a
ld a, h
ld [wPokegearRadioChannelAddr + 1], a
ret
NoRadioStation:
call NoRadioMusic
call NoRadioName
xor a
ld [wPokegearRadioChannelBank], a
ld [wPokegearRadioChannelAddr], a
ld [wPokegearRadioChannelAddr + 1], a
ld a, $1
ldh [hBGMapMode], a
ret
NoRadioMusic:
ld de, MUSIC_NONE
call PlayMusic
ld a, ENTER_MAP_MUSIC
ld [wPokegearRadioMusicPlaying], a
ret
NoRadioName:
xor a
ldh [hBGMapMode], a
hlcoord 1, 8
lb bc, 3, 18
call ClearBox
hlcoord 0, 12
lb bc, 4, 18
call Textbox
ret
OaksPKMNTalkName: db "OAK's <PK><MN> Talk@"
PokedexShowName: db "#DEX Show@"
PokemonMusicName: db "#MON Music@"
LuckyChannelName: db "Lucky Channel@"
UnownStationName: db "?????@"
PlacesAndPeopleName: db "Places & People@"
LetsAllSingName: db "Let's All Sing!@"
PokeFluteStationName: db "# FLUTE@"
_TownMap:
ld hl, wOptions
ld a, [hl]
push af
set NO_TEXT_SCROLL, [hl]
ldh a, [hInMenu]
push af
ld a, $1
ldh [hInMenu], a
ld a, [wVramState]
push af
xor a
ld [wVramState], a
call ClearBGPalettes
call ClearTilemap
call ClearSprites
call DisableLCD
call Pokegear_LoadGFX
farcall ClearSpriteAnims
ld a, 8
call SkipMusic
ld a, LCDC_DEFAULT
ldh [rLCDC], a
call TownMap_GetCurrentLandmark
ld [wTownMapPlayerIconLandmark], a
ld [wTownMapCursorLandmark], a
xor a
ldh [hBGMapMode], a
call .InitTilemap
call WaitBGMap2
ld a, [wTownMapPlayerIconLandmark]
call PokegearMap_InitPlayerIcon
ld a, [wTownMapCursorLandmark]
call PokegearMap_InitCursor
ld a, c
ld [wTownMapCursorObjectPointer], a
ld a, b
ld [wTownMapCursorObjectPointer + 1], a
ld b, SCGB_POKEGEAR_PALS
call GetSGBLayout
call SetPalettes
ldh a, [hCGB]
and a
jr z, .dmg
ld a, %11100100
call DmgToCgbObjPal0
call DelayFrame
.dmg
ld a, [wTownMapPlayerIconLandmark]
cp KANTO_LANDMARK
jr nc, .kanto
ld d, KANTO_LANDMARK - 1
ld e, 1
call .loop
jr .resume
.kanto
call TownMap_GetKantoLandmarkLimits
call .loop
.resume
pop af
ld [wVramState], a
pop af
ldh [hInMenu], a
pop af
ld [wOptions], a
call ClearBGPalettes
ret
.loop
call JoyTextDelay
ld hl, hJoyPressed
ld a, [hl]
and B_BUTTON
ret nz
ld hl, hJoyLast
ld a, [hl]
and D_UP
jr nz, .pressed_up
ld a, [hl]
and D_DOWN
jr nz, .pressed_down
.loop2
push de
farcall PlaySpriteAnimations
pop de
call DelayFrame
jr .loop
.pressed_up
ld hl, wTownMapCursorLandmark
ld a, [hl]
cp d
jr c, .okay
ld a, e
dec a
ld [hl], a
.okay
inc [hl]
jr .next
.pressed_down
ld hl, wTownMapCursorLandmark
ld a, [hl]
cp e
jr nz, .okay2
ld a, d
inc a
ld [hl], a
.okay2
dec [hl]
.next
push de
ld a, [wTownMapCursorLandmark]
call PokegearMap_UpdateLandmarkName
ld a, [wTownMapCursorObjectPointer]
ld c, a
ld a, [wTownMapCursorObjectPointer + 1]
ld b, a
ld a, [wTownMapCursorLandmark]
call PokegearMap_UpdateCursorPosition
pop de
jr .loop2
.InitTilemap:
ld a, [wTownMapPlayerIconLandmark]
cp KANTO_LANDMARK
jr nc, .kanto2
ld e, JOHTO_REGION
jr .okay_tilemap
.kanto2
ld e, KANTO_REGION
.okay_tilemap
farcall PokegearMap
ld a, $07
ld bc, 6
hlcoord 1, 0
call ByteFill
hlcoord 0, 0
ld [hl], $06
hlcoord 7, 0
ld [hl], $17
hlcoord 7, 1
ld [hl], $16
hlcoord 7, 2
ld [hl], $26
ld a, $07
ld bc, NAME_LENGTH
hlcoord 8, 2
call ByteFill
hlcoord 19, 2
ld [hl], $17
ld a, [wTownMapCursorLandmark]
call PokegearMap_UpdateLandmarkName
farcall TownMapPals
ret
PlayRadio:
ld hl, wOptions
ld a, [hl]
push af
set NO_TEXT_SCROLL, [hl]
call .PlayStation
ld c, 100
call DelayFrames
.loop
call JoyTextDelay
ldh a, [hJoyPressed]
and A_BUTTON | B_BUTTON
jr nz, .stop
ld a, [wPokegearRadioChannelAddr]
ld l, a
ld a, [wPokegearRadioChannelAddr + 1]
ld h, a
ld a, [wPokegearRadioChannelBank]
and a
jr z, .zero
rst FarCall
.zero
call DelayFrame
jr .loop
.stop
pop af
ld [wOptions], a
call ExitPokegearRadio_HandleMusic
ret
.PlayStation:
ld a, ENTER_MAP_MUSIC
ld [wPokegearRadioMusicPlaying], a
ld hl, .StationPointers
ld d, 0
add hl, de
add hl, de
ld a, [hli]
ld h, [hl]
ld l, a
ld de, .jump_return
push de
jp hl
.jump_return
push de
hlcoord 0, 12
lb bc, 4, 18
call Textbox
hlcoord 1, 14
ld [hl], "“"
pop de
hlcoord 2, 14
call PlaceString
ld h, b
ld l, c
ld [hl], "”"
call WaitBGMap
ret
.StationPointers:
; entries correspond to MAPRADIO_* constants
dw .OakOrPnP
dw LoadStation_OaksPokemonTalk
dw LoadStation_PokedexShow
dw LoadStation_PokemonMusic
dw LoadStation_LuckyChannel
dw LoadStation_UnownRadio
dw LoadStation_PlacesAndPeople
dw LoadStation_LetsAllSing
dw LoadStation_RocketRadio
.OakOrPnP:
call IsInJohto
and a
jr nz, .kanto
call UpdateTime
ld a, [wTimeOfDay]
and a
jp z, LoadStation_PokedexShow
jp LoadStation_OaksPokemonTalk
.kanto
jp LoadStation_PlacesAndPeople
PokegearMap:
ld a, e
and a
jr nz, .kanto
call LoadTownMapGFX
call FillJohtoMap
ret
.kanto
call LoadTownMapGFX
call FillKantoMap
ret
_FlyMap:
call ClearBGPalettes
call ClearTilemap
call ClearSprites
ld hl, hInMenu
ld a, [hl]
push af
ld [hl], $1
xor a
ldh [hBGMapMode], a
farcall ClearSpriteAnims
call LoadTownMapGFX
ld de, FlyMapLabelBorderGFX
ld hl, vTiles2 tile $30
lb bc, BANK(FlyMapLabelBorderGFX), 6
call Request1bpp
call FlyMap
call ret_91c8f
ld b, SCGB_POKEGEAR_PALS
call GetSGBLayout
call SetPalettes
.loop
call JoyTextDelay
ld hl, hJoyPressed
ld a, [hl]
and B_BUTTON
jr nz, .pressedB
ld a, [hl]
and A_BUTTON
jr nz, .pressedA
call FlyMapScroll
call GetMapCursorCoordinates
farcall PlaySpriteAnimations
call DelayFrame
jr .loop
.pressedB
ld a, -1
jr .exit
.pressedA
ld a, [wTownMapPlayerIconLandmark]
ld l, a
ld h, 0
add hl, hl
ld de, Flypoints + 1
add hl, de
ld a, [hl]
.exit
ld [wTownMapPlayerIconLandmark], a
pop af
ldh [hInMenu], a
call ClearBGPalettes
ld a, $90
ldh [hWY], a
xor a ; LOW(vBGMap0)
ldh [hBGMapAddress], a
ld a, HIGH(vBGMap0)
ldh [hBGMapAddress + 1], a
ld a, [wTownMapPlayerIconLandmark]
ld e, a
ret
FlyMapScroll:
ld a, [wStartFlypoint]
ld e, a
ld a, [wEndFlypoint]
ld d, a
ld hl, hJoyLast
ld a, [hl]
and D_UP
jr nz, .ScrollNext
ld a, [hl]
and D_DOWN
jr nz, .ScrollPrev
ret
.ScrollNext:
ld hl, wTownMapPlayerIconLandmark
ld a, [hl]
cp d
jr nz, .NotAtEndYet
ld a, e
dec a
ld [hl], a
.NotAtEndYet:
inc [hl]
call CheckIfVisitedFlypoint
jr z, .ScrollNext
jr .Finally
.ScrollPrev:
ld hl, wTownMapPlayerIconLandmark
ld a, [hl]
cp e
jr nz, .NotAtStartYet
ld a, d
inc a
ld [hl], a
.NotAtStartYet:
dec [hl]
call CheckIfVisitedFlypoint
jr z, .ScrollPrev
.Finally:
call TownMapBubble
call WaitBGMap
xor a
ldh [hBGMapMode], a
ret
TownMapBubble:
; Draw the bubble containing the location text in the town map HUD
; Top-left corner
hlcoord 1, 0
ld a, $30
ld [hli], a
; Top row
ld bc, 16
ld a, " "
call ByteFill
; Top-right corner
ld a, $31
ld [hl], a
hlcoord 1, 1
; Middle row
ld bc, SCREEN_WIDTH - 2
ld a, " "
call ByteFill
; Bottom-left corner
hlcoord 1, 2
ld a, $32
ld [hli], a
; Bottom row
ld bc, 16
ld a, " "
call ByteFill
; Bottom-right corner
ld a, $33
ld [hl], a
; Print "Where?"
hlcoord 2, 0
ld de, .Where
call PlaceString
; Print the name of the default flypoint
call .Name
; Up/down arrows
hlcoord 18, 1
ld [hl], $34
ret
.Where:
db "Where?@"
.Name:
; We need the map location of the default flypoint
ld a, [wTownMapPlayerIconLandmark]
ld l, a
ld h, 0
add hl, hl ; two bytes per flypoint
ld de, Flypoints
add hl, de
ld e, [hl]
farcall GetLandmarkName
hlcoord 2, 1
ld de, wStringBuffer1
call PlaceString
ret
GetMapCursorCoordinates:
ld a, [wTownMapPlayerIconLandmark]
ld l, a
ld h, 0
add hl, hl
ld de, Flypoints
add hl, de
ld e, [hl]
farcall GetLandmarkCoords
ld a, [wTownMapCursorCoordinates]
ld c, a
ld a, [wTownMapCursorCoordinates + 1]
ld b, a
ld hl, 4
add hl, bc
ld [hl], e
ld hl, 5
add hl, bc
ld [hl], d
ret
CheckIfVisitedFlypoint:
; Check if the flypoint loaded in [hl] has been visited yet.
push bc
push de
push hl
ld l, [hl]
ld h, 0
add hl, hl
ld de, Flypoints + 1
add hl, de
ld c, [hl]
call HasVisitedSpawn
pop hl
pop de
pop bc
and a
ret
HasVisitedSpawn:
; Check if spawn point c has been visited.
ld hl, wVisitedSpawns
ld b, CHECK_FLAG
ld d, 0
predef SmallFarFlagAction
ld a, c
ret
INCLUDE "data/maps/flypoints.asm"
ret_91c8f:
ret
FlyMap:
ld a, [wMapGroup]
ld b, a
ld a, [wMapNumber]
ld c, a
call GetWorldMapLocation
; If we're not in a valid location, i.e. Pokecenter floor 2F,
; the backup map information is used.
cp LANDMARK_SPECIAL
jr nz, .CheckRegion
ld a, [wBackupMapGroup]
ld b, a
ld a, [wBackupMapNumber]
ld c, a
call GetWorldMapLocation
.CheckRegion:
; The first 46 locations are part of Johto. The rest are in Kanto.
cp KANTO_LANDMARK
jr nc, .KantoFlyMap
.JohtoFlyMap:
; Note that .NoKanto should be modified in tandem with this branch
push af
; Start from New Bark Town
ld a, FLY_NEW_BARK
ld [wTownMapPlayerIconLandmark], a
; Flypoints begin at New Bark Town...
ld [wStartFlypoint], a
; ..and end at Silver Cave.
ld a, FLY_MT_SILVER
ld [wEndFlypoint], a
; Fill out the map
call FillJohtoMap
call .MapHud
pop af
call TownMapPlayerIcon
ret
.KantoFlyMap:
; The event that there are no flypoints enabled in a map is not
; accounted for. As a result, if you attempt to select a flypoint
; when there are none enabled, the game will crash. Additionally,
; the flypoint selection has a default starting point that
; can be flown to even if none are enabled.
; To prevent both of these things from happening when the player
; enters Kanto, fly access is restricted until Indigo Plateau is
; visited and its flypoint enabled.
push af
ld c, SPAWN_INDIGO
call HasVisitedSpawn
and a
jr z, .NoKanto
; Kanto's map is only loaded if we've visited Indigo Plateau
; Flypoints begin at Pallet Town...
ld a, FLY_PALLET
ld [wStartFlypoint], a
; ...and end at Indigo Plateau
ld a, FLY_INDIGO
ld [wEndFlypoint], a
; Because Indigo Plateau is the first flypoint the player
; visits, it's made the default flypoint.
ld [wTownMapPlayerIconLandmark], a
; Fill out the map
call FillKantoMap
call .MapHud
pop af
call TownMapPlayerIcon
ret
.NoKanto:
; If Indigo Plateau hasn't been visited, we use Johto's map instead
; Start from New Bark Town
ld a, FLY_NEW_BARK
ld [wTownMapPlayerIconLandmark], a
; Flypoints begin at New Bark Town...
ld [wStartFlypoint], a
; ..and end at Silver Cave
ld a, FLY_MT_SILVER
ld [wEndFlypoint], a
call FillJohtoMap
pop af
.MapHud:
call TownMapBubble
call TownMapPals
hlbgcoord 0, 0 ; BG Map 0
call TownMapBGUpdate
call TownMapMon
ld a, c
ld [wTownMapCursorCoordinates], a
ld a, b
ld [wTownMapCursorCoordinates + 1], a
ret
Pokedex_GetArea:
; e: Current landmark
ld a, [wTownMapPlayerIconLandmark]
push af
ld a, [wTownMapCursorLandmark]
push af
ld a, e
ld [wTownMapPlayerIconLandmark], a
call ClearSprites
xor a
ldh [hBGMapMode], a
ld a, $1
ldh [hInMenu], a
ld de, PokedexNestIconGFX
ld hl, vTiles0 tile $7f
lb bc, BANK(PokedexNestIconGFX), 1
call Request2bpp
call .GetPlayerOrFastShipIcon
ld hl, vTiles0 tile $78
ld c, 4
call Request2bpp
call LoadTownMapGFX
call FillKantoMap
call .PlaceString_MonsNest
call TownMapPals
hlbgcoord 0, 0, vBGMap1
call TownMapBGUpdate
call FillJohtoMap
call .PlaceString_MonsNest
call TownMapPals
hlbgcoord 0, 0
call TownMapBGUpdate
ld b, SCGB_POKEGEAR_PALS
call GetSGBLayout
call SetPalettes
xor a
ldh [hBGMapMode], a
xor a ; JOHTO_REGION
call .GetAndPlaceNest
.loop
call JoyTextDelay
ld hl, hJoyPressed
ld a, [hl]
and A_BUTTON | B_BUTTON
jr nz, .a_b
ldh a, [hJoypadDown]
and SELECT
jr nz, .select
call .LeftRightInput
call .BlinkNestIcons
jr .next
.select
call .HideNestsShowPlayer
.next
call DelayFrame
jr .loop
.a_b
call ClearSprites
pop af
ld [wTownMapCursorLandmark], a
pop af
ld [wTownMapPlayerIconLandmark], a
ret
.LeftRightInput:
ld a, [hl]
and D_LEFT
jr nz, .left
ld a, [hl]
and D_RIGHT
jr nz, .right
ret
.left
ldh a, [hWY]
cp $90
ret z
call ClearSprites
ld a, $90
ldh [hWY], a
xor a ; JOHTO_REGION
call .GetAndPlaceNest
ret
.right
ld a, [wStatusFlags]
bit STATUSFLAGS_HALL_OF_FAME_F, a
ret z
ldh a, [hWY]
and a
ret z
call ClearSprites
xor a
ldh [hWY], a
ld a, KANTO_REGION
call .GetAndPlaceNest
ret
.BlinkNestIcons:
ldh a, [hVBlankCounter]
ld e, a
and $f
ret nz
ld a, e
and $10
jr nz, .copy_sprites
call ClearSprites
ret
.copy_sprites
hlcoord 0, 0
ld de, wVirtualOAM
ld bc, wVirtualOAMEnd - wVirtualOAM
call CopyBytes
ret
.PlaceString_MonsNest:
hlcoord 0, 0
ld bc, SCREEN_WIDTH
ld a, " "
call ByteFill
hlcoord 0, 1
ld a, $06
ld [hli], a
ld bc, SCREEN_WIDTH - 2
ld a, $07
call ByteFill
ld [hl], $17
call GetPokemonName
hlcoord 2, 0
call PlaceString
ld h, b
ld l, c
ld de, .String_SNest
call PlaceString
ret
.String_SNest:
db "'S NEST@"
.GetAndPlaceNest:
ld [wTownMapCursorLandmark], a
ld e, a
farcall FindNest ; load nest landmarks into wTilemap[0,0]
decoord 0, 0
ld hl, wVirtualOAMSprite00
.nestloop
ld a, [de]
and a
jr z, .done_nest
push de
ld e, a
push hl
farcall GetLandmarkCoords
pop hl
; load into OAM
ld a, d
sub 4
ld [hli], a ; y
ld a, e
sub 4
ld [hli], a ; x
ld a, $7f ; nest icon
ld [hli], a ; tile id
xor a
ld [hli], a ; attributes
; next
pop de
inc de
jr .nestloop
.done_nest
ld hl, wVirtualOAM
decoord 0, 0
ld bc, wVirtualOAMEnd - wVirtualOAM
call CopyBytes
ret
.HideNestsShowPlayer:
call .CheckPlayerLocation
ret c
ld a, [wTownMapPlayerIconLandmark]
ld e, a
farcall GetLandmarkCoords
ld c, e
ld b, d
ld de, .PlayerOAM
ld hl, wVirtualOAMSprite00
.ShowPlayerLoop:
ld a, [de]
cp $80
jr z, .clear_oam
add b
ld [hli], a ; y
inc de
ld a, [de]
add c
ld [hli], a ; x
inc de
ld a, [de]
add $78 ; where the player's sprite is loaded
ld [hli], a ; tile id
inc de
push bc
ld c, PAL_OW_RED
ld a, [wPlayerGender]
bit PLAYERGENDER_FEMALE_F, a
jr z, .male
inc c ; PAL_OW_BLUE
.male
ld a, c
ld [hli], a ; attributes
pop bc
jr .ShowPlayerLoop
.clear_oam
ld hl, wVirtualOAMSprite04
ld bc, wVirtualOAMEnd - wVirtualOAMSprite04
xor a
call ByteFill
ret
.PlayerOAM:
; y pxl, x pxl, tile offset
db -1 * 8, -1 * 8, 0 ; top left
db -1 * 8, 0 * 8, 1 ; top right
db 0 * 8, -1 * 8, 2 ; bottom left
db 0 * 8, 0 * 8, 3 ; bottom right
db $80 ; terminator
.CheckPlayerLocation:
; Don't show the player's sprite if you're
; not in the same region as what's currently
; on the screen.
ld a, [wTownMapPlayerIconLandmark]
cp LANDMARK_FAST_SHIP
jr z, .johto
cp KANTO_LANDMARK
jr c, .johto
.kanto
ld a, [wTownMapCursorLandmark]
and a
jr z, .clear
jr .ok
.johto
ld a, [wTownMapCursorLandmark]
and a
jr nz, .clear
.ok
and a
ret
.clear
ld hl, wVirtualOAM
ld bc, wVirtualOAMEnd - wVirtualOAM
xor a
call ByteFill
scf
ret
.GetPlayerOrFastShipIcon:
ld a, [wTownMapPlayerIconLandmark]
cp LANDMARK_FAST_SHIP
jr z, .FastShip
farcall GetPlayerIcon
ret
.FastShip:
ld de, FastShipGFX
ld b, BANK(FastShipGFX)
ret
TownMapBGUpdate:
; Update BG Map tiles and attributes
; BG Map address
ld a, l
ldh [hBGMapAddress], a
ld a, h
ldh [hBGMapAddress + 1], a
; Only update palettes on CGB
ldh a, [hCGB]
and a
jr z, .tiles
; BG Map mode 2 (palettes)
ld a, 2
ldh [hBGMapMode], a
; The BG Map is updated in thirds, so we wait
; 3 frames to update the whole screen's palettes.
ld c, 3
call DelayFrames
.tiles
; Update BG Map tiles
call WaitBGMap
; Turn off BG Map update
xor a
ldh [hBGMapMode], a
ret
FillJohtoMap:
ld de, JohtoMap
jr FillTownMap
FillKantoMap:
ld de, KantoMap
FillTownMap:
hlcoord 0, 0
.loop
ld a, [de]
cp -1
ret z
ld a, [de]
ld [hli], a
inc de
jr .loop
TownMapPals:
; Assign palettes based on tile ids
hlcoord 0, 0
decoord 0, 0, wAttrmap
ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
.loop
; Current tile
ld a, [hli]
push hl
; The palette map covers tiles $00 to $5f; $60 and above use palette 0
cp $60
jr nc, .pal0
; The palette data is condensed to nybbles, least-significant first.
ld hl, .PalMap
srl a
jr c, .odd
; Even-numbered tile ids take the bottom nybble...
add l
ld l, a
ld a, h
adc 0
ld h, a
ld a, [hl]
and PALETTE_MASK
jr .update
.odd
; ...and odd ids take the top.
add l
ld l, a
ld a, h
adc 0
ld h, a
ld a, [hl]
swap a
and PALETTE_MASK
jr .update
.pal0
xor a
.update
pop hl
ld [de], a
inc de
dec bc
ld a, b
or c
jr nz, .loop
ret
.PalMap:
INCLUDE "gfx/pokegear/town_map_palette_map.asm"
TownMapMon:
; Draw the FlyMon icon at town map location
; Get FlyMon species
ld a, [wCurPartyMon]
ld hl, wPartySpecies
ld e, a
ld d, $0
add hl, de
ld a, [hl]
ld [wTempIconSpecies], a
; Get FlyMon icon
ld e, $08 ; starting tile in VRAM
farcall GetSpeciesIcon
; Animation/palette
depixel 0, 0
ld a, SPRITE_ANIM_INDEX_PARTY_MON
call InitSpriteAnimStruct
ld hl, SPRITEANIMSTRUCT_TILE_ID
add hl, bc
ld [hl], $08
ld hl, SPRITEANIMSTRUCT_ANIM_SEQ_ID
add hl, bc
ld [hl], SPRITE_ANIM_SEQ_NULL
ret
TownMapPlayerIcon:
; Draw the player icon at town map location in a
push af
farcall GetPlayerIcon
; Standing icon
ld hl, vTiles0 tile $10
ld c, 4 ; # tiles
call Request2bpp
; Walking icon
ld hl, $c0
add hl, de
ld d, h
ld e, l
ld hl, vTiles0 tile $14
ld c, 4 ; # tiles
ld a, BANK(ChrisSpriteGFX) ; does nothing
call Request2bpp
; Animation/palette
depixel 0, 0
ld b, SPRITE_ANIM_INDEX_RED_WALK ; Male
ld a, [wPlayerGender]
bit PLAYERGENDER_FEMALE_F, a
jr z, .got_gender
ld b, SPRITE_ANIM_INDEX_BLUE_WALK ; Female
.got_gender
ld a, b
call InitSpriteAnimStruct
ld hl, SPRITEANIMSTRUCT_TILE_ID
add hl, bc
ld [hl], $10
pop af
ld e, a
push bc
farcall GetLandmarkCoords
pop bc
ld hl, SPRITEANIMSTRUCT_XCOORD
add hl, bc
ld [hl], e
ld hl, SPRITEANIMSTRUCT_YCOORD
add hl, bc
ld [hl], d
ret
LoadTownMapGFX:
ld hl, TownMapGFX
ld de, vTiles2
lb bc, BANK(TownMapGFX), 48
call DecompressRequest2bpp
ret
JohtoMap:
INCBIN "gfx/pokegear/johto.bin"
KantoMap:
INCBIN "gfx/pokegear/kanto.bin"
PokedexNestIconGFX:
INCBIN "gfx/pokegear/dexmap_nest_icon.2bpp"
FlyMapLabelBorderGFX:
INCBIN "gfx/pokegear/flymap_label_border.1bpp"
Function92311:
xor a
ld [wTownMapPlayerIconLandmark], a
call ClearBGPalettes
call ClearTilemap
call ClearSprites
ld hl, hInMenu
ld a, [hl]
push af
ld [hl], $1
xor a
ldh [hBGMapMode], a
farcall ClearSpriteAnims
call LoadTownMapGFX
ld de, FlyMapLabelBorderGFX
ld hl, vTiles2 tile $30
lb bc, BANK(FlyMapLabelBorderGFX), 6
call Request1bpp
call FillKantoMap
call TownMapBubble
call TownMapPals
hlbgcoord 0, 0, vBGMap1
call TownMapBGUpdate
call FillJohtoMap
call TownMapBubble
call TownMapPals
hlbgcoord 0, 0
call TownMapBGUpdate
call TownMapMon
ld a, c
ld [wTownMapCursorCoordinates], a
ld a, b
ld [wTownMapCursorCoordinates + 1], a
ld b, SCGB_POKEGEAR_PALS
call GetSGBLayout
call SetPalettes
.loop
call JoyTextDelay
ld hl, hJoyPressed
ld a, [hl]
and B_BUTTON
jr nz, .pressedB
ld a, [hl]
and A_BUTTON
jr nz, .pressedA
call .HandleDPad
call GetMapCursorCoordinates
farcall PlaySpriteAnimations
call DelayFrame
jr .loop
.pressedB
ld a, -1
jr .finished_a_b
.pressedA
ld a, [wTownMapPlayerIconLandmark]
ld l, a
ld h, 0
add hl, hl
ld de, Flypoints + 1
add hl, de
ld a, [hl]
.finished_a_b
ld [wTownMapPlayerIconLandmark], a
pop af
ldh [hInMenu], a
call ClearBGPalettes
ld a, $90
ldh [hWY], a
xor a ; LOW(vBGMap0)
ldh [hBGMapAddress], a
ld a, HIGH(vBGMap0)
ldh [hBGMapAddress + 1], a
ld a, [wTownMapPlayerIconLandmark]
ld e, a
ret
.HandleDPad:
ld hl, hJoyLast
ld a, [hl]
and D_DOWN | D_RIGHT
jr nz, .down_right
ld a, [hl]
and D_UP | D_LEFT
jr nz, .up_left
ret
.down_right
ld hl, wTownMapPlayerIconLandmark
ld a, [hl]
cp FLY_INDIGO
jr c, .okay_dr
ld [hl], -1
.okay_dr
inc [hl]
jr .continue
.up_left
ld hl, wTownMapPlayerIconLandmark
ld a, [hl]
and a
jr nz, .okay_ul
ld [hl], FLY_INDIGO + 1
.okay_ul
dec [hl]
.continue
ld a, [wTownMapPlayerIconLandmark]
cp KANTO_FLYPOINT
jr c, .johto
call FillKantoMap
xor a
ld b, $9c
jr .finish
.johto
call FillJohtoMap
ld a, $90
ld b, $98
.finish
ldh [hWY], a
ld a, b
ldh [hBGMapAddress + 1], a
call TownMapBubble
call WaitBGMap
xor a
ldh [hBGMapMode], a
ret