summaryrefslogtreecommitdiff
path: root/engine
diff options
context:
space:
mode:
authorentrpntr <entrpntr@gmail.com>2020-05-08 13:19:28 -0400
committerentrpntr <entrpntr@gmail.com>2020-05-08 13:22:30 -0400
commitc4c838855a18dd928d49487e5f7fd02d65ce4766 (patch)
tree43b50c09e10e3a72e59348e6ea655b4544abd568 /engine
parent1220198362a209647b6491cb088e1e04204208cb (diff)
Add engine/phone/phone.asm.
Diffstat (limited to 'engine')
-rw-r--r--engine/phone/phone.asm732
1 files changed, 732 insertions, 0 deletions
diff --git a/engine/phone/phone.asm b/engine/phone/phone.asm
new file mode 100644
index 00000000..8ae66def
--- /dev/null
+++ b/engine/phone/phone.asm
@@ -0,0 +1,732 @@
+AddPhoneNumber::
+ call _CheckCellNum
+ jr c, .cant_add
+ call Phone_FindOpenSlot
+ jr nc, .cant_add
+ ld [hl], c
+ xor a
+ ret
+
+.cant_add
+ scf
+ ret
+
+DelCellNum::
+ call _CheckCellNum
+ jr nc, .not_in_list
+ xor a
+ ld [hl], a
+ ret
+
+.not_in_list
+ scf
+ ret
+
+CheckCellNum::
+ jp _CheckCellNum ; useless
+
+_CheckCellNum:
+ ld hl, wPhoneList
+ ld b, CONTACT_LIST_SIZE
+.loop
+ ld a, [hli]
+ cp c
+ jr z, .got_it
+ dec b
+ jr nz, .loop
+ xor a
+ ret
+
+.got_it
+ dec hl
+ scf
+ ret
+
+Phone_FindOpenSlot:
+ call GetRemainingSpaceInPhoneList
+ ld b, a
+ ld hl, wPhoneList
+.loop
+ ld a, [hli]
+ and a
+ jr z, .FoundOpenSpace
+ dec b
+ jr nz, .loop
+ xor a
+ ret
+
+.FoundOpenSpace:
+ dec hl
+ scf
+ ret
+
+GetRemainingSpaceInPhoneList:
+ xor a
+ ld [wBuffer1], a
+ ld hl, PermanentNumbers
+.loop
+ ld a, [hli]
+ cp -1
+ jr z, .done
+ cp c
+ jr z, .continue
+
+ push bc
+ push hl
+ ld c, a
+ call _CheckCellNum
+ jr c, .permanent
+ ld hl, wBuffer1
+ inc [hl]
+.permanent
+ pop hl
+ pop bc
+
+.continue
+ jr .loop
+
+.done
+ ld a, CONTACT_LIST_SIZE
+ ld hl, wBuffer1
+ sub [hl]
+ ret
+
+INCLUDE "data/phone/permanent_numbers.asm"
+
+FarPlaceString:
+ ldh a, [hROMBank]
+ push af
+ ld a, b
+ rst Bankswitch
+
+ call PlaceString
+
+ pop af
+ rst Bankswitch
+ ret
+
+CheckPhoneCall::
+; Check if the phone is ringing in the overworld.
+
+ call CheckStandingOnEntrance
+ jr z, .no_call
+
+ call .timecheck
+ nop
+ jr nc, .no_call
+
+ call Random
+ ld b, a
+ and 50 percent
+ cp b
+ jr nz, .no_call
+
+ call GetMapPhoneService
+ and a
+ jr nz, .no_call
+
+ call GetAvailableCallers
+ call ChooseRandomCaller
+ jr nc, .no_call
+
+ ld e, a
+ call LoadCallerScript
+ ld a, BANK(Script_ReceivePhoneCall)
+ ld hl, Script_ReceivePhoneCall
+ call CallScript
+ scf
+ ret
+
+.no_call
+ xor a
+ ret
+
+.timecheck
+ farcall CheckReceiveCallTimer
+ ret
+
+; unused
+ ret
+
+UnusedInitCallReceiveDelay:
+ farcall InitCallReceiveDelay
+ ret
+
+CheckPhoneContactTimeOfDay:
+ push hl
+ push bc
+ push de
+ push af
+
+ farcall CheckTime
+ pop af
+ and ANYTIME
+ and c
+
+ pop de
+ pop bc
+ pop hl
+ ret
+
+ChooseRandomCaller:
+; If no one is available to call, don't return anything.
+ ld a, [wNumAvailableCallers]
+ and a
+ jr z, .NothingToSample
+
+; Store the number of available callers in c.
+ ld c, a
+; Sample a random number between 0 and 31.
+ call Random
+ ldh a, [hRandomAdd]
+ swap a
+ and $1f
+; Compute that number modulo the number of available callers.
+ call SimpleDivide
+; Return the caller ID you just sampled.
+ ld c, a
+ ld b, 0
+ ld hl, wAvailableCallers
+ add hl, bc
+ ld a, [hl]
+ scf
+ ret
+
+.NothingToSample:
+ xor a
+ ret
+
+GetAvailableCallers:
+ farcall CheckTime
+ ld a, c
+ ld [wCheckedTime], a
+ ld hl, wNumAvailableCallers
+ ld bc, CONTACT_LIST_SIZE + 1
+ xor a
+ call ByteFill
+ ld de, wPhoneList
+ ld a, CONTACT_LIST_SIZE
+
+.loop
+ ld [wPhoneListIndex], a
+ ld a, [de]
+ and a
+ jr z, .not_good_for_call
+ ld hl, PhoneContacts + PHONE_CONTACT_SCRIPT2_TIME
+ ld bc, PHONE_CONTACT_SIZE
+ call AddNTimes
+ ld a, [wCheckedTime]
+ and [hl]
+ jr z, .not_good_for_call
+ ld bc, PHONE_CONTACT_MAP_GROUP - PHONE_CONTACT_SCRIPT2_TIME
+ add hl, bc
+ ld a, [wMapGroup]
+ cp [hl]
+ jr nz, .different_map
+ inc hl
+ ld a, [wMapNumber]
+ cp [hl]
+ jr z, .not_good_for_call
+.different_map
+ ld a, [wNumAvailableCallers]
+ ld c, a
+ ld b, $0
+ inc a
+ ld [wNumAvailableCallers], a
+ ld hl, wAvailableCallers
+ add hl, bc
+ ld a, [de]
+ ld [hl], a
+.not_good_for_call
+ inc de
+ ld a, [wPhoneListIndex]
+ dec a
+ jr nz, .loop
+ ret
+
+CheckSpecialPhoneCall::
+ ld a, [wSpecialPhoneCallID]
+ and a
+ jr z, .NoPhoneCall
+
+ dec a
+ ld c, a
+ ld b, 0
+ ld hl, SpecialPhoneCallList
+ ld a, 6
+ call AddNTimes
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ call _hl_
+ jr nc, .NoPhoneCall
+
+ call .DoSpecialPhoneCall
+ inc hl
+ inc hl
+ ld a, [hli]
+ ld e, a
+ push hl
+ call LoadCallerScript
+ pop hl
+ ld de, wCallerContact + PHONE_CONTACT_SCRIPT2_BANK
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hli]
+ ld [de], a
+ ld a, BANK(.script)
+ ld hl, .script
+ call CallScript
+ scf
+ ret
+.NoPhoneCall:
+ xor a
+ ret
+
+.script
+ pause 30
+ sjump Script_ReceivePhoneCall
+
+.DoSpecialPhoneCall:
+ ld a, [wSpecialPhoneCallID]
+ dec a
+ ld c, a
+ ld b, 0
+ ld hl, SpecialPhoneCallList
+ ld a, 6
+ call AddNTimes
+ ret
+
+SpecialCallOnlyWhenOutside:
+ ld a, [wEnvironment]
+ cp TOWN
+ jr z, .outside
+ cp ROUTE
+ jr z, .outside
+ xor a
+ ret
+
+.outside
+ scf
+ ret
+
+SpecialCallWhereverYouAre:
+ scf
+ ret
+
+Function90199:
+ ; Don't do the call if you're in a link communication
+ ld a, [wLinkMode]
+ and a
+ jr nz, .OutOfArea
+ ; If you're in an area without phone service, don't do the call
+ call GetMapPhoneService
+ and a
+ jr nz, .OutOfArea
+ ; If the person can't take a call at that time, don't do the call
+ ld a, b
+ ld [wCurCaller], a
+ ld hl, PhoneContacts
+ ld bc, PHONE_CONTACT_SIZE
+ call AddNTimes
+ ld d, h
+ ld e, l
+ ld hl, PHONE_CONTACT_SCRIPT1_TIME
+ add hl, de
+ ld a, [hl]
+ call CheckPhoneContactTimeOfDay
+ jr z, .OutOfArea
+ ; If we're in the same map as the person we're calling,
+ ; use the "Just talk to that person" script.
+ ld hl, PHONE_CONTACT_MAP_GROUP
+ add hl, de
+ ld a, [wMapGroup]
+ cp [hl]
+ jr nz, .GetPhoneScript
+ ld hl, PHONE_CONTACT_MAP_NUMBER
+ add hl, de
+ ld a, [wMapNumber]
+ cp [hl]
+ jr nz, .GetPhoneScript
+ ld b, BANK(PhoneScript_JustTalkToThem)
+ ld hl, PhoneScript_JustTalkToThem
+ jr .DoPhoneCall
+
+.GetPhoneScript:
+ ld hl, PHONE_CONTACT_SCRIPT1_BANK
+ add hl, de
+ ld b, [hl]
+ ld hl, PHONE_CONTACT_SCRIPT1_ADDR_LO
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jr .DoPhoneCall
+
+.OutOfArea:
+ ld b, BANK(LoadOutOfAreaScript)
+ ld de, LoadOutOfAreaScript
+ call ExecuteCallbackScript
+ ret
+
+.DoPhoneCall:
+ ld a, b
+ ld [wPhoneScriptBank], a
+ ld a, l
+ ld [wPhoneCaller], a
+ ld a, h
+ ld [wPhoneCaller + 1], a
+ ld b, BANK(LoadPhoneScriptBank)
+ ld de, LoadPhoneScriptBank
+ call ExecuteCallbackScript
+ ret
+
+LoadPhoneScriptBank:
+ memcall wPhoneScriptBank
+ return
+
+LoadOutOfAreaScript:
+ scall PhoneOutOfAreaScript
+ return
+
+LoadCallerScript:
+ nop
+ nop
+ ld a, e
+ ld [wCurCaller], a
+ and a
+ jr nz, .actualcaller
+ ld hl, WrongNumber
+ ld a, BANK(WrongNumber)
+ jr .proceed
+
+.actualcaller
+ ld hl, PhoneContacts
+ ld bc, PHONE_CONTACT_SIZE
+ ld a, e
+ call AddNTimes
+ ld a, BANK(PhoneContacts)
+.proceed
+ ld de, wCallerContact
+ ld bc, PHONE_CONTACT_SIZE
+ call FarCopyBytes
+ ret
+
+WrongNumber:
+ db TRAINER_NONE, PHONE_00
+ dba .script
+.script
+ writetext .PhoneWrongNumberText
+ end
+.PhoneWrongNumberText:
+ text_far _PhoneWrongNumberText
+ text_end
+
+Script_ReceivePhoneCall:
+ refreshscreen
+ callasm RingTwice_StartCall
+ memcall wCallerContact + PHONE_CONTACT_SCRIPT2_BANK
+ waitbutton
+ callasm HangUp
+ closetext
+ callasm InitCallReceiveDelay
+ end
+
+Script_SpecialBillCall::
+ callasm .LoadBillScript
+ sjump Script_ReceivePhoneCall
+
+.LoadBillScript:
+ ld e, PHONE_BILL
+ jp LoadCallerScript
+
+LoadElmCallScript:
+ callasm .LoadElmScript
+ pause 30
+ sjump Script_ReceivePhoneCall
+
+.LoadElmScript:
+ ld e, PHONE_ELM
+ jp LoadCallerScript
+
+RingTwice_StartCall:
+ call .Ring
+; fall through (rings a second time)
+.Ring:
+ call Phone_StartRinging
+ call Phone_Wait20Frames
+ call Phone_CallerTextboxWithName
+ call Phone_Wait20Frames
+ call Phone_CallerTextbox
+ call Phone_Wait20Frames
+ call Phone_CallerTextboxWithName
+ ret
+
+Phone_CallerTextboxWithName:
+ ld a, [wCurCaller]
+ ld b, a
+ call Function90363
+ ret
+
+PhoneCall::
+ ld a, b
+ ld [wPhoneScriptBank], a
+ ld a, e
+ ld [wPhoneCaller], a
+ ld a, d
+ ld [wPhoneCaller + 1], a
+ call Phone_Ring
+; fall through (rings a second time)
+Phone_Ring:
+ call Phone_StartRinging
+ call Phone_Wait20Frames
+ call Phone_CallerTextboxWithName2
+ call Phone_Wait20Frames
+ call Phone_CallerTextbox
+ call Phone_Wait20Frames
+ call Phone_CallerTextboxWithName2
+ ret
+
+Phone_CallerTextboxWithName2:
+ call Phone_CallerTextbox
+ hlcoord 1, 2
+ ld [hl], "☎"
+ inc hl
+ inc hl
+ ld a, [wPhoneScriptBank]
+ ld b, a
+ ld a, [wPhoneCaller]
+ ld e, a
+ ld a, [wPhoneCaller + 1]
+ ld d, a
+ call FarPlaceString
+ ret
+
+Phone_NoSignal:
+ ld de, SFX_NO_SIGNAL
+ call PlaySFX
+ jr Phone_CallEnd
+
+HangUp::
+ call HangUp_Beep
+ call HangUp_Wait20Frames
+Phone_CallEnd:
+ call HangUp_BoopOn
+ call HangUp_Wait20Frames
+ call HangUp_BoopOff
+ call HangUp_Wait20Frames
+ call HangUp_BoopOn
+ call HangUp_Wait20Frames
+ call HangUp_BoopOff
+ call HangUp_Wait20Frames
+ call HangUp_BoopOn
+ call HangUp_Wait20Frames
+ call HangUp_BoopOff
+ call HangUp_Wait20Frames
+ ret
+
+Function90316:
+ ld de, SFX_SHUT_DOWN_PC
+ call PlaySFX
+ ret
+
+HangUp_Beep:
+ ld hl, PhoneClickText
+ call PrintText
+ ld de, SFX_HANG_UP
+ call PlaySFX
+ ret
+
+PhoneClickText:
+ text_far _PhoneClickText
+ text_end
+
+HangUp_BoopOn:
+ ld hl, PhoneEllipseText
+ call PrintText
+ ret
+
+PhoneEllipseText:
+ text_far _PhoneEllipseText
+ text_end
+
+HangUp_BoopOff:
+ call SpeechTextbox
+ ret
+
+Phone_StartRinging:
+ call WaitSFX
+ ld de, SFX_CALL
+ call PlaySFX
+ call Phone_CallerTextbox
+ call UpdateSprites
+ farcall PhoneRing_CopyTilemapAtOnce
+ ret
+
+HangUp_Wait20Frames:
+ jr Phone_Wait20Frames
+
+Phone_Wait20Frames:
+ ld c, 20
+ call DelayFrames
+ farcall PhoneRing_CopyTilemapAtOnce
+ ret
+
+Function90363:
+ push bc
+ call Phone_CallerTextbox
+ hlcoord 1, 1
+ ld [hl], "☎"
+ inc hl
+ inc hl
+ ld d, h
+ ld e, l
+ pop bc
+ call Function90380
+ ret
+
+Phone_CallerTextbox:
+ hlcoord 0, 0
+ ld b, 2
+ ld c, SCREEN_WIDTH - 2
+ call Textbox
+ ret
+
+Function90380:
+ ld h, d
+ ld l, e
+ ld a, b
+ call GetCallerTrainerClass
+ call GetCallerName
+ ret
+
+CheckCanDeletePhoneNumber:
+ ld a, c
+ call GetCallerTrainerClass
+ ld a, c
+ ; and a
+ ret nz
+ ld a, b
+ cp PHONECONTACT_MOM
+ ret z
+ cp PHONECONTACT_ELM
+ ret z
+ ld c, $1
+ ret
+
+GetCallerTrainerClass:
+ push hl
+ ld hl, PhoneContacts + PHONE_CONTACT_TRAINER_CLASS
+ ld bc, PHONE_CONTACT_SIZE
+ call AddNTimes
+ ld a, [hli]
+ ld b, [hl]
+ ld c, a
+ pop hl
+ ret
+
+GetCallerName:
+ ld a, c
+ and a
+ jr z, .NotTrainer
+
+ call Phone_GetTrainerName
+ push hl
+ push bc
+ call PlaceString
+ ld a, ":"
+ ld [bc], a
+ pop bc
+ pop hl
+ ld de, SCREEN_WIDTH + 3
+ add hl, de
+ call Phone_GetTrainerClassName
+ call PlaceString
+ ret
+
+.NotTrainer:
+ push hl
+ ld c, b
+ ld b, 0
+ ld hl, NonTrainerCallerNames
+ add hl, bc
+ add hl, bc
+ ld a, [hli]
+ ld e, a
+ ld d, [hl]
+ pop hl
+ call PlaceString
+ ld a, ":"
+ ld [bc], a
+ ret
+
+INCLUDE "data/phone/non_trainer_names.asm"
+
+Phone_GetTrainerName:
+ push hl
+ push bc
+ farcall GetTrainerName
+ pop bc
+ pop hl
+ ret
+
+Phone_GetTrainerClassName:
+ push hl
+ push bc
+ farcall GetTrainerClassName
+ pop bc
+ pop hl
+ ret
+
+GetCallerLocation:
+ ld a, [wCurCaller]
+ call GetCallerTrainerClass
+ ld d, c
+ ld e, b
+ push de
+ ld a, [wCurCaller]
+ ld hl, PhoneContacts + PHONE_CONTACT_MAP_GROUP
+ ld bc, PHONE_CONTACT_SIZE
+ call AddNTimes
+ ld b, [hl]
+ inc hl
+ ld c, [hl]
+ push bc
+ call GetWorldMapLocation
+ ld e, a
+ farcall GetLandmarkName
+ pop bc
+ pop de
+ ret
+
+INCLUDE "data/phone/phone_contacts.asm"
+
+INCLUDE "data/phone/special_calls.asm"
+
+PhoneOutOfAreaScript:
+ writetext PhoneOutOfAreaText
+ end
+
+PhoneOutOfAreaText:
+ text_far _PhoneOutOfAreaText
+ text_end
+
+PhoneScript_JustTalkToThem:
+ writetext PhoneJustTalkToThemText
+ end
+
+PhoneJustTalkToThemText:
+ text_far _PhoneJustTalkToThemText
+ text_end
+
+PhoneThankYouTextScript:
+ writetext PhoneThankYouText
+ end
+
+PhoneThankYouText:
+ text_far _PhoneThankYouText
+ text_end