summaryrefslogtreecommitdiff
path: root/engine/link
diff options
context:
space:
mode:
Diffstat (limited to 'engine/link')
-rw-r--r--engine/link/init_list.asm4
-rw-r--r--engine/link/link.asm89
-rw-r--r--engine/link/mystery_gift.asm971
-rw-r--r--engine/link/mystery_gift_2.asm28
-rw-r--r--engine/link/mystery_gift_3.asm4
-rw-r--r--engine/link/time_capsule.asm12
6 files changed, 622 insertions, 486 deletions
diff --git a/engine/link/init_list.asm b/engine/link/init_list.asm
index b85cf001..3e16d349 100644
--- a/engine/link/init_list.asm
+++ b/engine/link/init_list.asm
@@ -44,9 +44,9 @@ InitList:
ld a, h
ld [wListPointer + 1], a
ld a, e
- ld [wUnusedCFFE], a
+ ld [wUnusedNamesPointer], a
ld a, d
- ld [wUnusedCFFE + 1], a
+ ld [wUnusedNamesPointer + 1], a
ld bc, ItemAttributes
ld a, c
ld [wItemAttributesPtr], a
diff --git a/engine/link/link.asm b/engine/link/link.asm
index 789e3d5e..2d8d458b 100644
--- a/engine/link/link.asm
+++ b/engine/link/link.asm
@@ -25,10 +25,11 @@ LinkCommunications:
hlcoord 4, 10
ld de, String_PleaseWait
call PlaceString
- ld hl, wce5d
- xor a ; LOW($5000)
+ ld hl, wLinkByteTimeout
+ assert LOW(SERIAL_LINK_BYTE_TIMEOUT) == 0
+ xor a ; LOW(SERIAL_LINK_BYTE_TIMEOUT)
ld [hli], a
- ld [hl], HIGH($5000)
+ ld [hl], HIGH(SERIAL_LINK_BYTE_TIMEOUT)
ld a, [wLinkMode]
cp LINK_TIMECAPSULE
jp nz, Gen2ToGen2LinkComms
@@ -82,9 +83,9 @@ Gen2ToGen1LinkComms:
call Serial_ExchangeBytes
ld a, SERIAL_NO_DATA_BYTE
ld [de], a
- ld hl, wLink_c508
+ ld hl, wc508
ld de, wTrademons
- ld bc, wTrademons - wLink_c508
+ ld bc, wTrademons - wc508
call Serial_ExchangeBytes
xor a
ldh [rIF], a
@@ -105,8 +106,8 @@ Gen2ToGen1LinkComms:
ld de, wLinkData
ld bc, $1a2
call Link_CopyOTData
- ld de, wPlayerTrademonSpecies
- ld hl, wTimeCapsulePartyMon1Species
+ ld de, wPlayerTrademon
+ ld hl, wTimeCapsulePlayerData
ld c, 2
.loop
ld a, [de]
@@ -160,12 +161,12 @@ Gen2ToGen1LinkComms:
.done_party
ld [de], a
- ld hl, wTimeCapsulePartyMon1Species
+ ld hl, wTimeCapsulePlayerData
call Link_ConvertPartyStruct1to2
ld a, LOW(wOTPartyMonOT)
- ld [wUnusedCFFE], a
+ ld [wUnusedNamesPointer], a
ld a, HIGH(wOTPartyMonOT)
- ld [wUnusedCFFE + 1], a
+ ld [wUnusedNamesPointer + 1], a
ld de, MUSIC_NONE
call PlayMusic
ldh a, [hSerialConnectionStatus]
@@ -226,9 +227,9 @@ Gen2ToGen2LinkComms:
call Serial_ExchangeBytes
ld a, SERIAL_NO_DATA_BYTE
ld [de], a
- ld hl, wLink_c508
+ ld hl, wc508
ld de, wTrademons
- ld bc, wTrademons - wLink_c508
+ ld bc, wTrademons - wc508
call Serial_ExchangeBytes
ld a, [wLinkMode]
cp LINK_TRADECENTER
@@ -251,8 +252,8 @@ Gen2ToGen2LinkComms:
ld de, wLinkData
ld bc, $1b9
call Link_CopyOTData
- ld de, wPlayerTrademonSpecies
- ld hl, wLinkPlayerPartyMon1Species
+ ld de, wPlayerTrademon
+ ld hl, wLinkPlayerData
ld c, 2
.loop1
ld a, [de]
@@ -377,9 +378,9 @@ Gen2ToGen2LinkComms:
ld bc, wOTPartyDataEnd - wOTPartyMons
call CopyBytes
ld a, LOW(wOTPartyMonOT)
- ld [wUnusedCFFE], a
+ ld [wUnusedNamesPointer], a
ld a, HIGH(wOTPartyMonOT)
- ld [wUnusedCFFE + 1], a
+ ld [wUnusedNamesPointer + 1], a
ld de, MUSIC_NONE
call PlayMusic
ldh a, [hSerialConnectionStatus]
@@ -451,6 +452,8 @@ LinkTimeout:
text_end
ExchangeBytes:
+; This is similar to Serial_ExchangeBytes,
+; but without a SERIAL_PREAMBLE_BYTE check.
ld a, TRUE
ldh [hSerialIgnoringInitialData], a
.loop
@@ -461,9 +464,9 @@ ExchangeBytes:
ld b, a
inc hl
ld a, 48
-.delay_cycles
+.wait
dec a
- jr nz, .delay_cycles
+ jr nz, .wait
ldh a, [hSerialIgnoringInitialData]
and a
ld a, b
@@ -514,7 +517,7 @@ FixDataForLinkTransfer:
ld [hli], a
dec b
jr nz, .loop2
- ld hl, wLink_c508
+ ld hl, wc508
ld a, SERIAL_PREAMBLE_BYTE
ld [hli], a
ld [hli], a
@@ -525,7 +528,7 @@ FixDataForLinkTransfer:
ld [hli], a
dec b
jr nz, .loop3
- ld hl, wTimeCapsulePartyMon1 - 1 + PARTY_LENGTH
+ ld hl, wTimeCapsulePlayerData - 1 + PARTY_LENGTH
ld de, wc512
lb bc, 0, 0
.loop4
@@ -1301,13 +1304,13 @@ LinkTrade_TradeStatsMenu:
pop af
ld [wMenuCursorY], a
dec a
- ld [wceed], a
+ ld [wCurTradePartyMon], a
ld [wPlayerLinkAction], a
call Serial_PrintWaitingTextAndSyncAndExchangeNybble
ld a, [wOtherPlayerLinkMode]
cp $f
jp z, InitTradeMenuDisplay
- ld [wceee], a
+ ld [wCurOTTradePartyMon], a
call LinkTradePlaceArrow
ld c, 100
call DelayFrames
@@ -1331,7 +1334,7 @@ LinkTrade_TradeStatsMenu:
xor a
ld [wce57], a
ld [wOtherPlayerLinkAction], a
- ld a, [wceee]
+ ld a, [wCurOTTradePartyMon]
ld hl, wOTPartySpecies
ld c, a
ld b, 0
@@ -1407,7 +1410,7 @@ LinkTradeCheckCancel:
jr nz, .loop1
ExitLinkCommunications:
xor a
- ld [wd8b7], a
+ ld [wUnusedLinkCommunicationByte], a
xor a
ldh [rSB], a
ldh [hSerialSend], a
@@ -1471,7 +1474,7 @@ LinkTrade:
ld b, 4
ld c, 18
call LinkTextboxAtHL
- ld a, [wceed]
+ ld a, [wCurTradePartyMon]
ld hl, wPartySpecies
ld c, a
ld b, 0
@@ -1480,10 +1483,10 @@ LinkTrade:
ld [wNamedObjectIndexBuffer], a
call GetPokemonName
ld hl, wStringBuffer1
- ld de, wceef
+ ld de, wBufferTrademonNick
ld bc, MON_NAME_LENGTH
call CopyBytes
- ld a, [wceee]
+ ld a, [wCurOTTradePartyMon]
ld hl, wOTPartySpecies
ld c, a
ld b, 0
@@ -1562,7 +1565,7 @@ LinkTrade:
.do_trade:
ld hl, sPartyMail
- ld a, [wceed]
+ ld a, [wCurTradePartyMon]
ld bc, MAIL_STRUCT_LENGTH
call AddNTimes
ld a, BANK(sPartyMail)
@@ -1571,7 +1574,7 @@ LinkTrade:
ld e, l
ld bc, MAIL_STRUCT_LENGTH
add hl, bc
- ld a, [wceed]
+ ld a, [wCurTradePartyMon]
ld c, a
.copy_mail
inc c
@@ -1592,7 +1595,7 @@ LinkTrade:
call AddNTimes
push hl
ld hl, wc8f4
- ld a, [wceee]
+ ld a, [wCurOTTradePartyMon]
ld bc, MAIL_STRUCT_LENGTH
call AddNTimes
pop de
@@ -1607,7 +1610,7 @@ LinkTrade:
ld bc, NAME_LENGTH
call CopyBytes
; species
- ld a, [wceed]
+ ld a, [wCurTradePartyMon]
ld hl, wPartySpecies
ld b, 0
ld c, a
@@ -1616,7 +1619,7 @@ LinkTrade:
ld [wPlayerTrademonSpecies], a
push af
; OT name
- ld a, [wceed]
+ ld a, [wCurTradePartyMon]
ld hl, wPartyMonOT
call SkipNames
ld de, wPlayerTrademonOTName
@@ -1624,7 +1627,7 @@ LinkTrade:
call CopyBytes
; ID
ld hl, wPartyMon1ID
- ld a, [wceed]
+ ld a, [wCurTradePartyMon]
call GetPartyLocation
ld a, [hli]
ld [wPlayerTrademonID], a
@@ -1632,7 +1635,7 @@ LinkTrade:
ld [wPlayerTrademonID + 1], a
; DVs
ld hl, wPartyMon1DVs
- ld a, [wceed]
+ ld a, [wCurTradePartyMon]
call GetPartyLocation
ld a, [hli]
ld [wPlayerTrademonDVs], a
@@ -1646,7 +1649,7 @@ LinkTrade:
ld bc, NAME_LENGTH
call CopyBytes
; species
- ld a, [wceee]
+ ld a, [wCurOTTradePartyMon]
ld hl, wOTPartySpecies
ld b, 0
ld c, a
@@ -1654,7 +1657,7 @@ LinkTrade:
ld a, [hl]
ld [wOTTrademonSpecies], a
; OT name
- ld a, [wceee]
+ ld a, [wCurOTTradePartyMon]
ld hl, wOTPartyMonOT
call SkipNames
ld de, wOTTrademonOTName
@@ -1662,7 +1665,7 @@ LinkTrade:
call CopyBytes
; ID
ld hl, wOTPartyMon1ID
- ld a, [wceee]
+ ld a, [wCurOTTradePartyMon]
call GetPartyLocation
ld a, [hli]
ld [wOTTrademonID], a
@@ -1670,21 +1673,21 @@ LinkTrade:
ld [wOTTrademonID + 1], a
; DVs
ld hl, wOTPartyMon1DVs
- ld a, [wceee]
+ ld a, [wCurOTTradePartyMon]
call GetPartyLocation
ld a, [hli]
ld [wOTTrademonDVs], a
ld a, [hl]
ld [wOTTrademonDVs + 1], a
- ld a, [wceed]
+ ld a, [wCurTradePartyMon]
ld [wCurPartyMon], a
ld hl, wPartySpecies
ld b, 0
ld c, a
add hl, bc
ld a, [hl]
- ld [wceed], a
+ ld [wCurTradePartyMon], a
xor a ; REMOVE_PARTY
ld [wPokemonWithdrawDepositParameter], a
@@ -1694,14 +1697,14 @@ LinkTrade:
ld [wCurPartyMon], a
ld a, TRUE
ld [wForceEvolution], a
- ld a, [wceee]
+ ld a, [wCurOTTradePartyMon]
push af
ld hl, wOTPartySpecies
ld b, 0
ld c, a
add hl, bc
ld a, [hl]
- ld [wceee], a
+ ld [wCurOTTradePartyMon], a
ld c, 100
call DelayFrames
@@ -2129,7 +2132,7 @@ CheckLinkTimeout_Receptionist:
ld a, $1
ld [wPlayerLinkAction], a
ld hl, wLinkTimeoutFrames
- ld a, $3
+ ld a, 3
ld [hli], a
xor a
ld [hl], a
diff --git a/engine/link/mystery_gift.asm b/engine/link/mystery_gift.asm
index dcea2e8c..f6ddc93a 100644
--- a/engine/link/mystery_gift.asm
+++ b/engine/link/mystery_gift.asm
@@ -1,3 +1,27 @@
+; hMGRole values
+IR_RECEIVER EQU 1
+IR_SENDER EQU 2
+
+; hMGStatusFlags error bits
+MG_WRONG_CHECKSUM_F EQU 0
+MG_TIMED_OUT_F EQU 1
+MG_CANCELED_F EQU 4
+MG_WRONG_PREFIX_F EQU 7
+
+; hMGStatusFlags values
+MG_WRONG_CHECKSUM EQU 1 << MG_WRONG_CHECKSUM_F
+MG_TIMED_OUT EQU 1 << MG_TIMED_OUT_F
+MG_CANCELED EQU 1 << MG_CANCELED_F
+MG_WRONG_PREFIX EQU 1 << MG_WRONG_PREFIX_F
+MG_NOT_OKAY EQU MG_WRONG_CHECKSUM | MG_TIMED_OUT | MG_CANCELED | MG_WRONG_PREFIX
+MG_OKAY EQU $ff ^ MG_NOT_OKAY
+MG_START_END EQU %11111111
+
+REGION_PREFIX EQU $96
+REGION_CODE EQU $90 ; USA
+
+MESSAGE_PREFIX EQU $5a
+
DoMysteryGift:
call ClearTilemap
call ClearSprites
@@ -7,22 +31,24 @@ DoMysteryGift:
ld de, .String_PressAToLink_BToCancel
call PlaceString
call WaitBGMap
- farcall PrepMysteryGiftDataToSend
- call MysteryGift_ClearTrainerData
- ld a, $2
- ld [wc901], a
- ld a, $14
- ld [wc902], a
- ldh a, [rIE]
- push af
- call Function29fc9
+ ; Prepare the first of two messages for wMysteryGiftPartnerData
+ farcall StageDataForMysteryGift
+ call ClearMysteryGiftTrainer
+ ld a, 2
+ ld [wMysteryGiftMessageCount], a
+ ld a, wMysteryGiftPartnerDataEnd - wMysteryGiftPartnerData
+ ld [wMysteryGiftStagedDataLength], a
+ ldh a, [rIE]
+ push af
+ call ExchangeMysteryGiftData
ld d, a
xor a
ldh [rIF], a
pop af
ldh [rIE], a
+
push de
call ClearTilemap
call EnableLCD
@@ -31,15 +57,16 @@ DoMysteryGift:
call GetSGBLayout
call SetPalettes
pop de
+
hlcoord 2, 8
ld a, d
ld de, .MysteryGiftCanceledText ; Link has been canceled
- cp $10
+ cp MG_CANCELED
jp z, .LinkCanceled
- cp $6c
+ cp MG_OKAY
jp nz, .CommunicationError
- ld a, [wc800]
- cp 3
+ ld a, [wMysteryGiftGameVersion]
+ cp POKEMON_PIKACHU_2_VERSION
jr z, .skip_checks
call .CheckAlreadyGotFiveGiftsToday
ld hl, .MysteryGiftFiveADayText ; Only 5 gifts a day
@@ -54,25 +81,27 @@ DoMysteryGift:
ld a, [wMysteryGiftPartnerBackupItem]
and a
jr nz, .FriendNotReady
- ld a, [wc800]
- cp 3
+ ld a, [wMysteryGiftGameVersion]
+ cp POKEMON_PIKACHU_2_VERSION
jr z, .skip_append_save
call .AddMysteryGiftPartnerID
- ld a, [wc800]
- cp 4
+ ld a, [wMysteryGiftGameVersion]
+ cp 4 ; ???
jr z, .skip_append_save
call .SaveMysteryGiftTrainerName
.skip_append_save
ld a, [wMysteryGiftPartnerSentDeco]
and a
- jr z, .item
+ jr z, .SentItem
+; sent decoration
ld a, [wMysteryGiftPartnerWhichDeco]
ld c, a
farcall MysteryGiftGetDecoration
push bc
- call MysteryGift_CheckAndSetDecorationAlreadyReceived
+ call CheckAndSetMysteryGiftDecorationAlreadyReceived
pop bc
- jr nz, .item
+ jr nz, .SentItem
+; keep the decoration if it wasn't already received
callfar GetDecorationName_c
ld h, d
ld l, e
@@ -82,17 +111,17 @@ DoMysteryGift:
ld hl, .MysteryGiftSentHomeText ; sent decoration to home
jr .PrintTextAndExit
-.item
+.SentItem:
call GetMysteryGiftBank
ld a, [wMysteryGiftPartnerWhichItem]
ld c, a
- farcall MysteryGiftGetItemHeldEffect
+ farcall MysteryGiftGetItem
ld a, c
ld [sBackupMysteryGiftItem], a
ld [wNamedObjectIndexBuffer], a
call CloseSRAM
call GetItemName
- ld hl, .MysteryGiftSentText ; sent item
+ ld hl, .MysteryGiftSentText ; sent item/decoration
jr .PrintTextAndExit
.LinkCanceled:
@@ -110,6 +139,7 @@ DoMysteryGift:
.FriendNotReady:
ld hl, .YourFriendIsNotReadyText ; friend not ready
+ ; fallthrough
.PrintTextAndExit:
call PrintText
@@ -159,7 +189,7 @@ DoMysteryGift:
.CheckAlreadyGotFiveGiftsToday:
call GetMysteryGiftBank
ld a, [sNumDailyMysteryGiftPartnerIDs]
- cp $5
+ cp MAX_MYSTERY_GIFT_PARTNERS
jp CloseSRAM
.CheckAlreadyGotAGiftFromThatPerson:
@@ -195,9 +225,9 @@ DoMysteryGift:
ld hl, sNumDailyMysteryGiftPartnerIDs
ld a, [hl]
inc [hl]
- ld hl, sDailyMysteryGiftPartnerIDs ; inc hl
+ ld hl, sDailyMysteryGiftPartnerIDs ; could have done "inc hl" instead
ld e, a
- ld d, $0
+ ld d, 0
add hl, de
add hl, de
ld a, [wMysteryGiftPartnerID]
@@ -208,223 +238,264 @@ DoMysteryGift:
.SaveMysteryGiftTrainerName:
call GetMysteryGiftBank
- ld a, $1
+ ld a, TRUE
ld [sMysteryGiftTrainerHouseFlag], a
ld hl, wMysteryGiftPartnerName
ld de, sMysteryGiftPartnerName
ld bc, NAME_LENGTH
call CopyBytes
- ld a, $1
+ assert sMysteryGiftPartnerName + NAME_LENGTH == sMysteryGiftUnusedFlag
+ ld a, TRUE
ld [de], a
inc de
- ld hl, wMysteryGiftTrainerData
- ld bc, (1 + 1 + NUM_MOVES) * PARTY_LENGTH + 2
+ assert sMysteryGiftUnusedFlag + 1 == sMysteryGiftTrainer
+ ld hl, wMysteryGiftTrainer
+ ld bc, wMysteryGiftTrainerEnd - wMysteryGiftTrainer
call CopyBytes
jp CloseSRAM
-Function29fc9:
+ExchangeMysteryGiftData:
farcall ClearChannels
- call Function2a18c
+ call InitializeIRCommunicationInterrupts
-.loop2
- call Function2a1c4
- call Function2a20b
+.restart
+ call BeginIRCommunication
+ call InitializeIRCommunicationRoles
ldh a, [hMGStatusFlags]
- cp $10
- jp z, Function2a103
- cp $6c
- jr nz, .loop2
-
- ldh a, [hPrintNumBuffer + 8]
- cp $2
- jr z, Function2a055
- ld hl, hPrintNumBuffer
- ld b, $1
- call Function2a184
- jr nz, .ly_loop
- call Function2a07c
- jp nz, Function2a103
- jr Function2a03d
+ cp MG_CANCELED
+ jp z, EndOrContinueMysteryGiftIRCommunication
+ cp MG_OKAY
+ jr nz, .restart
+
+ ldh a, [hMGRole]
+ cp IR_SENDER
+ jr z, SenderExchangeMysteryGiftDataPayloads
+; receiver
+ ld hl, hMGExchangedByte
+ ld b, 1
+ call TryReceivingIRDataBlock
+ jr nz, .failed
+ call ReceiveMysteryGiftDataPayload_GotRegionPrefix
+ jp nz, EndOrContinueMysteryGiftIRCommunication
+ jr ReceiverExchangeMysteryGiftDataPayloads_GotPayload
+
+.failed
; Delay frame
-.ly_loop
+.wait_frame
ldh a, [rLY]
cp LY_VBLANK
- jr c, .ly_loop
+ jr c, .wait_frame
+
ld c, LOW(rRP)
- ld a, $c0
+ ld a, rRP_ENABLE_READ_MASK
ldh [c], a
- ld b, 240 ; This might have been intended as a 4-second timeout buffer.
- ; However, it is reset with each frame.
-.loop3
- push bc
- call MysteryGift_ReadJoypad
- ld b, $2
+ ld b, 60 * 4 ; 4 seconds
+.continue
+ push bc
+ call MysteryGift_UpdateJoypad
+ ld b, 1 << rRP_RECEIVING
ld c, LOW(rRP)
- ; Delay frame
-.ly_loop2
+.in_vblank
ldh a, [c]
and b
ld b, a
ldh a, [rLY]
cp LY_VBLANK
- jr nc, .ly_loop2
-.ly_loop3
+ jr nc, .in_vblank
+.wait_vblank
ldh a, [c]
and b
ld b, a
ldh a, [rLY]
cp LY_VBLANK
- jr c, .ly_loop3
-
+ jr c, .wait_vblank
ld a, b
pop bc
+ ; Restart if the 4-second timeout has elapsed
dec b
- jr z, .loop2 ; we never jump here
+ jr z, .restart
+ ; Restart if rRP is not receiving data
or a
- jr nz, .loop2
- ; Check if we've pressed the B button
+ jr nz, .restart
+ ; Check if we've pressed the B button to cancel
ldh a, [hMGJoypadReleased]
bit B_BUTTON_F, a
- jr z, .loop3
- ld a, $10
+ jr z, .continue
+ ld a, MG_CANCELED
ldh [hMGStatusFlags], a
- jp Function2a103
-
-Function2a037:
- call Function2a073
- jp nz, Function2a103
-; fallthrough
-Function2a03d:
- call Function2a166
- jp nz, Function2a103
- call Function2a0bb
- jp nz, Function2a103
- call Function2a171
- jp nz, Function2a103
- call Function2a461
- jp Function2a103
-
-Function2a055:
- call Function2a0bb
- jp nz, Function2a103
- call Function2a171
- jp nz, Function2a103
- call Function2a073
- jp nz, Function2a103
- call Function2a166
- jp nz, Function2a103
- call Function2a45c
- jp Function2a103
-
-Function2a073:
- ld hl, hPrintNumBuffer
- ld b, $1
- call Function2a184
+ jp EndOrContinueMysteryGiftIRCommunication
+
+ReceiverExchangeMysteryGiftDataPayloads:
+ ; Receive the data payload
+ call ReceiveMysteryGiftDataPayload
+ jp nz, EndOrContinueMysteryGiftIRCommunication
+ ; fallthrough
+ReceiverExchangeMysteryGiftDataPayloads_GotPayload:
+ ; Switch roles
+ call BeginSendingIRCommunication
+ jp nz, EndOrContinueMysteryGiftIRCommunication
+ ; Send the data payload
+ call SendMysteryGiftDataPayload
+ jp nz, EndOrContinueMysteryGiftIRCommunication
+ ; Switch roles
+ call BeginReceivingIRCommunication
+ jp nz, EndOrContinueMysteryGiftIRCommunication
+ ; Receive an empty block
+ call ReceiveEmptyIRDataBlock
+ jp EndOrContinueMysteryGiftIRCommunication
+
+SenderExchangeMysteryGiftDataPayloads:
+ ; Send the data payload
+ call SendMysteryGiftDataPayload
+ jp nz, EndOrContinueMysteryGiftIRCommunication
+ ; Switch roles
+ call BeginReceivingIRCommunication
+ jp nz, EndOrContinueMysteryGiftIRCommunication
+ ; Receive the data payload
+ call ReceiveMysteryGiftDataPayload
+ jp nz, EndOrContinueMysteryGiftIRCommunication
+ ; Switch roles
+ call BeginSendingIRCommunication
+ jp nz, EndOrContinueMysteryGiftIRCommunication
+ ; Send an empty block
+ call SendEmptyIRDataBlock
+ jp EndOrContinueMysteryGiftIRCommunication
+
+ReceiveMysteryGiftDataPayload:
+ ; Receive the region prefix
+ ld hl, hMGExchangedByte
+ ld b, 1
+ call TryReceivingIRDataBlock
ret nz
-; fallthrough
-Function2a07c:
- call Function2a461
+ ; fallthrough
+ReceiveMysteryGiftDataPayload_GotRegionPrefix:
+ ; Receive an empty block
+ call ReceiveEmptyIRDataBlock
ldh a, [hMGStatusFlags]
- cp $6c
+ cp MG_OKAY
ret nz
- ldh a, [hPrintNumBuffer]
- cp $96
- jp nz, Function2a160
- ld a, $90
- ldh [hPrintNumBuffer], a
- call Function2a166
+ ; Verify the received region prefix
+ ldh a, [hMGExchangedByte]
+ cp REGION_PREFIX
+ jp nz, WrongMysteryGiftRegion
+ ld a, REGION_CODE
+ ldh [hMGExchangedByte], a
+ ; Switch roles
+ call BeginSendingIRCommunication
ret nz
- ld hl, hPrintNumBuffer
- ld b, $1
- call Function2a17c
+ ; Send the region code
+ ld hl, hMGExchangedByte
+ ld b, 1
+ call TrySendingIRDataBlock
ret nz
- call Function2a45c
+ ; Send an empty block
+ call SendEmptyIRDataBlock
ldh a, [hMGStatusFlags]
- cp $6c
+ cp MG_OKAY
ret nz
- call Function2a171
+ ; Switch roles
+ call BeginReceivingIRCommunication
ret nz
- ld hl, wMysteryGiftTrainerData
- ld a, [wc902]
+ ; Receive the staged data
+ ld hl, wMysteryGiftTrainer
+ ld a, [wMysteryGiftStagedDataLength]
ld b, a
- call Function2a184
+ call TryReceivingIRDataBlock
ret nz
- call Function2a461
+ ; Receive an empty block
+ call ReceiveEmptyIRDataBlock
ldh a, [hMGStatusFlags]
- cp $6c
+ cp MG_OKAY
ret
-Function2a0bb:
- ld a, $96
- ldh [hPrintNumBuffer], a
- ld hl, hPrintNumBuffer
- ld b, $1
- call Function2a17c
+SendMysteryGiftDataPayload:
+ ; Send the region prefix
+ ld a, REGION_PREFIX
+ ldh [hMGExchangedByte], a
+ ld hl, hMGExchangedByte
+ ld b, 1
+ call TrySendingIRDataBlock
ret nz
- call Function2a45c
+ ; Send an empty block
+ call SendEmptyIRDataBlock
ldh a, [hMGStatusFlags]
- cp $6c
+ cp MG_OKAY
ret nz
- call Function2a171
+ ; Switch roles
+ call BeginReceivingIRCommunication
ret nz
- ld hl, hPrintNumBuffer
- ld b, $1
- call Function2a184
+ ; Receive the region code
+ ld hl, hMGExchangedByte
+ ld b, 1
+ call TryReceivingIRDataBlock
ret nz
- call Function2a461
+ ; Receive an empty block
+ call ReceiveEmptyIRDataBlock
ldh a, [hMGStatusFlags]
- cp $6c
+ cp MG_OKAY
ret nz
- ldh a, [hPrintNumBuffer]
- cp $90
- jp nz, Function2a160
- call Function2a166
+ ; Verify the received region code
+ ldh a, [hMGExchangedByte]
+ cp REGION_CODE
+ jp nz, WrongMysteryGiftRegion
+ ; Switch roles
+ call BeginSendingIRCommunication
ret nz
- ld hl, wLinkData
- ld a, [wc902]
+ ; Send the staged data
+ ld hl, wMysteryGiftStaging
+ ld a, [wMysteryGiftStagedDataLength]
ld b, a
- call Function2a17c
+ call TrySendingIRDataBlock
ret nz
- call Function2a45c
+ ; Send an empty block
+ call SendEmptyIRDataBlock
ldh a, [hMGStatusFlags]
- cp $6c
+ cp MG_OKAY
ret
-Function2a103:
+EndOrContinueMysteryGiftIRCommunication:
nop
ldh a, [hMGStatusFlags]
- cp $10
+ ; Quit if player canceled
+ cp MG_CANCELED
jr z, .quit
- cp $6c
+ ; Quit if there was a communication error
+ cp MG_OKAY
jr nz, .quit
- ld hl, wc901
+ ; Quit if all messages are sent/received
+ ld hl, wMysteryGiftMessageCount
dec [hl]
jr z, .quit
- ld hl, wMysteryGiftTrainerData
+ ; Quit if communicating with Pokémon Pikachu 2 device
+ ld hl, wMysteryGiftTrainer
ld de, wMysteryGiftPartnerData
ld bc, wMysteryGiftPartnerDataEnd - wMysteryGiftPartnerData
call CopyBytes
- ld a, [wMysteryGiftTrainerData]
- cp $3
+ ld a, [wMysteryGiftTrainer] ; first byte is the version
+ cp POKEMON_PIKACHU_2_VERSION
jr nc, .quit
+
+ ; Prepare the second message for wMysteryGiftTrainer
farcall StagePartyDataForMysteryGift
- call MysteryGift_ClearTrainerData
- ld a, $26
- ld [wc902], a
- ldh a, [hPrintNumBuffer + 8]
- cp $2
- jr z, .asm_2a143
- call Function2a171
- jr nz, Function2a103
- jp Function2a037
-
-.asm_2a143
- call Function2a166
- jr nz, Function2a103
- jp Function2a055
-
-.quit:
+ call ClearMysteryGiftTrainer
+ ld a, wMysteryGiftTrainerEnd - wMysteryGiftTrainer
+ ld [wMysteryGiftStagedDataLength], a
+
+ ldh a, [hMGRole]
+ cp IR_SENDER
+ jr z, .sender
+; receiver
+ call BeginReceivingIRCommunication
+ jr nz, EndOrContinueMysteryGiftIRCommunication
+ jp ReceiverExchangeMysteryGiftDataPayloads
+
+.sender
+ call BeginSendingIRCommunication
+ jr nz, EndOrContinueMysteryGiftIRCommunication
+ jp SenderExchangeMysteryGiftDataPayloads
+
+.quit
xor a
ldh [rIF], a
ldh a, [rIE]
@@ -434,50 +505,50 @@ Function2a103:
call DelayFrame
ldh a, [hMGStatusFlags]
push af
- call Function2a1ce
+ call EndIRCommunication
pop af
ret
-Function2a160:
- ld a, $80
+WrongMysteryGiftRegion:
+ ld a, MG_WRONG_PREFIX
ldh [hMGStatusFlags], a
and a
ret
-Function2a166:
- call Function2a1c4
- call Function2a274
+BeginSendingIRCommunication:
+ call BeginIRCommunication
+ call SendIRHelloMessage
ldh a, [hMGStatusFlags]
- cp $6c
+ cp MG_OKAY
ret
-Function2a171:
- call Function2a1c4
- call Function2a22c
+BeginReceivingIRCommunication:
+ call BeginIRCommunication
+ call ReceiveIRHelloMessage
ldh a, [hMGStatusFlags]
- cp $6c
+ cp MG_OKAY
ret
-Function2a17c:
- call Function2a2c1
+TrySendingIRDataBlock:
+ call SendIRDataBlock
ldh a, [hMGStatusFlags]
- cp $6c
+ cp MG_OKAY
ret
-Function2a184:
- call Function2a385
+TryReceivingIRDataBlock:
+ call ReceiveIRDataBlock
ldh a, [hMGStatusFlags]
- cp $6c
+ cp MG_OKAY
ret
-Function2a18c:
- call Function2a1a2
+InitializeIRCommunicationInterrupts:
+ call StartFastIRTimer
ld a, 1 << TIMER
ldh [rIE], a
xor a
ldh [rIF], a
- call Function2a1c4
-; runs for ~$40400 cycles
+ call BeginIRCommunication
+; waits for ~$40400 cycles = ~0.25 seconds
xor a
ld b, a
.busy_wait
@@ -487,69 +558,76 @@ Function2a18c:
jr nz, .busy_wait
ret
-Function2a1a2:
+StartFastIRTimer:
+; Starts a 65,536 Hz timer that interrupts every 3 increments (21,845 Hz).
xor a
ldh [rTAC], a
- ld a, $fe
+ ld a, -2
ldh [rTMA], a
ldh [rTIMA], a
- ld a, $2
+ ld a, rTAC_65536_HZ
ldh [rTAC], a
- or $4
+ or 1 << rTAC_ON
ldh [rTAC], a
ret
-Function2a1b4:
+StartSlowIRTimer:
+; Starts a 65,536 Hz timer that interrupts every 256 increments (256 Hz).
xor a
ldh [rTAC], a
ldh [rTMA], a
ldh [rTIMA], a
- ld a, $2
+ ld a, rTAC_65536_HZ
ldh [rTAC], a
- or $4
+ or 1 << rTAC_ON
ldh [rTAC], a
ret
-Function2a1c4:
- ld a, $c0
- call Function2a2ba
- ld a, $1
- ldh [hPrintNumBuffer + 8], a
+BeginIRCommunication:
+ ld a, rRP_ENABLE_READ_MASK
+ call ToggleIRCommunication
+ ld a, IR_RECEIVER
+ ldh [hMGRole], a
ret
-Function2a1ce:
+EndIRCommunication:
xor a
- call Function2a2ba
- ld a, $2
+ call ToggleIRCommunication
+ ld a, rTAC_65536_HZ
ldh [rTAC], a
ret
-Function2a1d7:
+ReceiveInfraredLEDOn:
+; Count interrupts of the partner's IR LED on; quit after 256-d interrupts.
+.recv_loop
inc d
ret z
xor a
ldh [rIF], a
halt
ldh a, [c]
- bit 1, a
- jr z, Function2a1d7
+ bit rRP_RECEIVING, a
+ jr z, .recv_loop
or a
ret
-Function2a1e5:
+ReceiveInfraredLEDOff:
+; Count interrupts of the partner's IR LED off; quit after 256-d interrupts.
+.no_recv_loop
inc d
ret z
xor a
ldh [rIF], a
halt
ldh a, [c]
- bit 1, a
- jr nz, Function2a1e5
+ bit rRP_RECEIVING, a
+ jr nz, .no_recv_loop
or a
ret
-Function2a1f3:
- ld a, $c1
+SendInfraredLEDOn:
+; Holds the IR LED on for d-1 interrupts.
+ ld a, rRP_ENABLE_READ_MASK | (1 << rRP_LED_ON)
ldh [c], a
.wait
dec d
@@ -559,8 +637,9 @@ Function2a1f3:
halt
jr .wait
-Function2a1ff:
- ld a, $c0
+SendInfraredLEDOff:
+; Holds the IR LED off for d-1 interrupts.
+ ld a, rRP_ENABLE_READ_MASK
ldh [c], a
.wait
dec d
@@ -570,175 +649,204 @@ Function2a1ff:
halt
jr .wait
-Function2a20b:
- ld d, $0
+InitializeIRCommunicationRoles:
+ ld d, 0
ld e, d
- ld a, $1
- ldh [hPrintNumBuffer + 8], a
+
+ ld a, IR_RECEIVER
+ ldh [hMGRole], a
.loop
- call MysteryGift_ReadJoypad
- ld b, $2
+ call MysteryGift_UpdateJoypad
+ ld b, 1 << rRP_RECEIVING
ld c, LOW(rRP)
+ ; Check if we've pressed the B button to cancel
ldh a, [hMGJoypadReleased]
bit B_BUTTON_F, a
- jr z, .next
- ld a, $10
+ jr z, .not_canceled
+ ld a, MG_CANCELED
ldh [hMGStatusFlags], a
ret
-.next
- bit 0, a
- jr nz, Function2a268
+.not_canceled
+ ; Check if we've pressed the A button to start sending
+ bit A_BUTTON_F, a
+ jr nz, SendIRHelloMessageAfterDelay
+ ; If rRP is not receiving data, keep checking for input
ldh a, [c]
and b
jr nz, .loop
+ ; fallthrough
-Function2a22c:
+ReceiveIRHelloMessage:
ld c, LOW(rRP)
- ld d, $0
+ ld d, 0
ld e, d
- call Function2a1e5
- jp z, Function2a370
+
+ call ReceiveInfraredLEDOff
+ jp z, InfraredLEDReceiveTimedOut
ld d, e
- call Function2a1d7
- jp z, Function2a370
- call Function2a1e5
- jp z, Function2a370
- call Function2a1d7
- jp z, Function2a370
- ld a, $6c
+ call ReceiveInfraredLEDOn
+ jp z, InfraredLEDReceiveTimedOut
+ call ReceiveInfraredLEDOff
+ jp z, InfraredLEDReceiveTimedOut
+ call ReceiveInfraredLEDOn
+ jp z, InfraredLEDReceiveTimedOut
+
+ ld a, MG_OKAY
ldh [hMGStatusFlags], a
- ld d, $3d
- call Function2a1ff
- ld d, $5
- call Function2a1f3
- ld d, $15
- call Function2a1ff
- ld d, $5
- call Function2a1f3
- ld d, $5
- call Function2a1ff
+
+ ld d, 61
+ call SendInfraredLEDOff
+ ld d, 5
+ call SendInfraredLEDOn
+ ld d, 21
+ call SendInfraredLEDOff
+ ld d, 5
+ call SendInfraredLEDOn
+ ld d, 5
+ call SendInfraredLEDOff
ret
-Function2a268:
+SendIRHelloMessageAfterDelay:
; Wait a random amount of time
call Random
ld e, a
and $f
ld d, a
-.loop
+.wait_loop
dec de
ld a, d
or e
- jr nz, .loop
-Function2a274:
- ld a, $2
- ldh [hPrintNumBuffer + 8], a
+ jr nz, .wait_loop
+ ; fallthrough
+
+SendIRHelloMessage:
+ ld a, IR_SENDER
+ ldh [hMGRole], a
+
ld c, LOW(rRP)
- ld d, $0
+ ld d, 0
ld e, d
- ld d, $3d
- call Function2a1ff
- ld d, $5
- call Function2a1f3
- ld d, $15
- call Function2a1ff
- ld d, $5
- call Function2a1f3
- ld d, $5
- call Function2a1ff
+
+ ld d, 61
+ call SendInfraredLEDOff
+ ld d, 5
+ call SendInfraredLEDOn
+ ld d, 21
+ call SendInfraredLEDOff
+ ld d, 5
+ call SendInfraredLEDOn
+ ld d, 5
+ call SendInfraredLEDOff
+
ld d, e
- call Function2a1e5
- jp z, Function2a370
+ call ReceiveInfraredLEDOff
+ jp z, InfraredLEDReceiveTimedOut
ld d, e
- call Function2a1d7
- jp z, Function2a370
- call Function2a1e5
- jp z, Function2a370
- call Function2a1d7
- jp z, Function2a370
- ld d, $3d
- call Function2a1ff
- ld a, $6c
+ call ReceiveInfraredLEDOn
+ jp z, InfraredLEDReceiveTimedOut
+ call ReceiveInfraredLEDOff
+ jp z, InfraredLEDReceiveTimedOut
+ call ReceiveInfraredLEDOn
+ jp z, InfraredLEDReceiveTimedOut
+
+ ld d, 61
+ call SendInfraredLEDOff
+
+ ld a, MG_OKAY
ldh [hMGStatusFlags], a
ret
-Function2a2ba:
+ToggleIRCommunication:
ldh [rRP], a
- ld a, $ff
+ ld a, MG_START_END
ldh [hMGStatusFlags], a
ret
-Function2a2c1:
+SendIRDataBlock:
+; Send b bytes of data in three messages:
+; 1. two bytes: MESSAGE_PREFIX and the length b
+; 2. b bytes: the actual data
+; 3. two bytes: a little-endian checksum
+; Then receive a one-byte acknowledgement message: the status.
xor a
- ldh [hPrintNumBuffer + 4], a
- ldh [hPrintNumBuffer + 5], a
+ ldh [hMGChecksum + 0], a
+ ldh [hMGChecksum + 1], a
push hl
push bc
ld c, LOW(rRP)
- ld d, $3d
- call Function2a1ff
- ld hl, hPrintNumBuffer + 1
- ld a, $5a
+ ld d, 61
+ call SendInfraredLEDOff
+ ld hl, hMGExchangedWord
+ ld a, MESSAGE_PREFIX
ld [hli], a
ld [hl], b
dec hl
- ld b, $2
- call Function2a304
+ ld b, 2
+ call SendIRDataMessage
pop bc
pop hl
- call Function2a304
- ldh a, [hPrintNumBuffer + 4]
- ldh [hPrintNumBuffer + 1], a
- ldh a, [hPrintNumBuffer + 5]
- ldh [hPrintNumBuffer + 2], a
+ call SendIRDataMessage
+ ldh a, [hMGChecksum + 0]
+ ldh [hMGExchangedWord + 0], a
+ ldh a, [hMGChecksum + 1]
+ ldh [hMGExchangedWord + 1], a
push hl
- ld hl, hPrintNumBuffer + 1
- ld b, $2
- call Function2a304
+ ld hl, hMGExchangedWord
+ ld b, 2
+ call SendIRDataMessage
ld hl, hMGStatusFlags
- ld b, $1
- call Function2a3dd
- ldh a, [hPrintNumBuffer + 1]
- ldh [hPrintNumBuffer + 4], a
- ldh a, [hPrintNumBuffer + 2]
- ldh [hPrintNumBuffer + 5], a
+ ld b, 1
+ call ReceiveIRDataMessage
+ ldh a, [hMGExchangedWord + 0]
+ ldh [hMGChecksum + 0], a
+ ldh a, [hMGExchangedWord + 1]
+ ldh [hMGChecksum + 1], a
pop hl
ret
-Function2a304:
+SendIRDataMessage:
+; Send b bytes of data one bit at a time, and update the checksum.
ld c, LOW(rRP)
- ld d, $5
- call Function2a1ff
- ld d, $5
- call Function2a1f3
- ld d, $15
- call Function2a1ff
+
+ ld d, 5
+ call SendInfraredLEDOff
+ ld d, 5
+ call SendInfraredLEDOn
+ ld d, 21
+ call SendInfraredLEDOff
+
+ ; b = -b - 1; then count up to 0
ld a, b
cpl
ld b, a
- ld a, $f4
+
+ ld a, -12
ldh [rTMA], a
-.main_loop
+.byte_loop
inc b
jr z, .done
- ld a, $8
- ldh [hPrintNumBuffer + 3], a
+ ld a, 8
+ ldh [hMGNumBits], a
+ ; Get the next data byte
ld a, [hli]
ld e, a
- ldh a, [hPrintNumBuffer + 4]
+ ; Add the next data byte to the checksum
+ ldh a, [hMGChecksum + 0]
add e
- ldh [hPrintNumBuffer + 4], a
- ldh a, [hPrintNumBuffer + 5]
+ ldh [hMGChecksum + 0], a
+ ldh a, [hMGChecksum + 1]
adc 0
- ldh [hPrintNumBuffer + 5], a
-.inner_loop
+ ldh [hMGChecksum + 1], a
+ ; Send each bit of the byte
+.bit_loop
xor a
ldh [rIF], a
halt
- ld a, $c1
+ ld a, rRP_ENABLE_READ_MASK | (1 << rRP_LED_ON)
ldh [rRP], a
- ld d, $1
+ ; Turn the LED off for longer if the bit is 1
+ ld d, 1
ld a, e
rlca
ld e, a
@@ -746,9 +854,9 @@ Function2a304:
inc d
.wait
ldh a, [rTIMA]
- cp $f8
+ cp -8
jr c, .wait
- ld a, $c0
+ ld a, rRP_ENABLE_READ_MASK
ldh [rRP], a
dec d
jr z, .no_halt
@@ -756,133 +864,145 @@ Function2a304:
ldh [rIF], a
halt
.no_halt
- ldh a, [hPrintNumBuffer + 3]
+ ldh a, [hMGNumBits]
dec a
- jr z, .main_loop
- ldh [hPrintNumBuffer + 3], a
- jr .inner_loop
+ jr z, .byte_loop
+ ldh [hMGNumBits], a
+ jr .bit_loop
.done
- ld a, $fe
+ ld a, -2
ldh [rTMA], a
xor a
ldh [rIF], a
halt
- ld d, $5
- call Function2a1f3
- ld d, $11
- call Function2a1ff
+
+ ld d, 5
+ call SendInfraredLEDOn
+ ld d, 17
+ call SendInfraredLEDOff
ret
-Function2a370:
+InfraredLEDReceiveTimedOut:
ldh a, [hMGStatusFlags]
- or $2
+ or MG_TIMED_OUT
ldh [hMGStatusFlags], a
ret
-Function2a377:
+ReceivedWrongIRChecksum:
ldh a, [hMGStatusFlags]
- or $1
+ or MG_WRONG_CHECKSUM
ldh [hMGStatusFlags], a
ret
-Function2a37e:
+ReceivedWrongIRMessagePrefix:
ldh a, [hMGStatusFlags]
- or $80
+ or MG_WRONG_PREFIX
ldh [hMGStatusFlags], a
ret
-Function2a385:
+ReceiveIRDataBlock:
+; Receive b bytes of data in three messages:
+; 1. two bytes: MESSAGE_PREFIX and the length b
+; 2. b bytes: the actual data
+; 3. two bytes: a little-endian checksum
+; Then send a one-byte acknowledgement message: the status.
xor a
- ldh [hPrintNumBuffer + 4], a
- ldh [hPrintNumBuffer + 5], a
+ ldh [hMGChecksum + 0], a
+ ldh [hMGChecksum + 1], a
push bc
push hl
- ld hl, hPrintNumBuffer + 1
- ld b, $2
- call Function2a3dd
- ldh a, [hPrintNumBuffer + 2]
- ldh [hPrintNumBuffer + 7], a
+ ld hl, hMGExchangedWord
+ ld b, 2
+ call ReceiveIRDataMessage
+ ldh a, [hMGExchangedWord + 1]
+ ldh [hMGUnusedMsgLength], a
ld b, a
pop hl
pop af
cp b
- jp c, Function2a37e
- ldh a, [hPrintNumBuffer + 1]
- cp $5a
- jp nz, Function2a37e
- call Function2a3dd
- ldh a, [hPrintNumBuffer + 4]
+ jp c, ReceivedWrongIRMessagePrefix
+ ldh a, [hMGExchangedWord + 0]
+ cp MESSAGE_PREFIX
+ jp nz, ReceivedWrongIRMessagePrefix
+ call ReceiveIRDataMessage
+ ldh a, [hMGChecksum + 0]
ld d, a
- ldh a, [hPrintNumBuffer + 5]
+ ldh a, [hMGChecksum + 1]
ld e, a
push hl
push de
- ld hl, hPrintNumBuffer + 1
- ld b, $2
- call Function2a3dd
+ ld hl, hMGExchangedWord
+ ld b, 2
+ call ReceiveIRDataMessage
pop de
- ld hl, hPrintNumBuffer + 1
+ ld hl, hMGExchangedWord
ld a, [hli]
xor d
ld b, a
ld a, [hl]
xor e
or b
- call nz, Function2a377
+ call nz, ReceivedWrongIRChecksum
push de
- ld d, $3d
- call Function2a1ff
+
+ ld d, 61
+ call SendInfraredLEDOff
+
ld hl, hMGStatusFlags
- ld b, $1
- call Function2a304
+ ld b, 1
+ call SendIRDataMessage
+
pop de
pop hl
ld a, d
- ldh [hPrintNumBuffer + 4], a
+ ldh [hMGChecksum + 0], a
ld a, e
- ldh [hPrintNumBuffer + 5], a
+ ldh [hMGChecksum + 1], a
ret
-Function2a3dd:
+ReceiveIRDataMessage:
ld c, LOW(rRP)
- ld d, $0
- call Function2a1e5
- jp z, Function2a370
- ld d, $0
- call Function2a1d7
- jp z, Function2a370
- ld d, $0
- call Function2a1e5
- jp z, Function2a370
+
+ ld d, 0
+ call ReceiveInfraredLEDOff
+ jp z, InfraredLEDReceiveTimedOut
+ ld d, 0
+ call ReceiveInfraredLEDOn
+ jp z, InfraredLEDReceiveTimedOut
+ ld d, 0
+ call ReceiveInfraredLEDOff
+ jp z, InfraredLEDReceiveTimedOut
+
ld a, b
cpl
ld b, a
xor a
ldh [hMGPrevTIMA], a
- call Function2a1b4
+
+ call StartSlowIRTimer
.main_loop
inc b
jr z, .done
- ld a, $8
- ldh [hPrintNumBuffer + 3], a
+ ld a, 8
+ ldh [hMGNumBits], a
.inner_loop
- ld d, $0
-.wait_one
+ ld d, 0
+.recv_loop
inc d
- jr z, .got_one
+ jr z, .recv_done
ldh a, [c]
- bit 1, a
- jr z, .wait_one
- ld d, $0
-.got_one
-.wait_zero
+ bit rRP_RECEIVING, a
+ jr z, .recv_loop
+ ld d, 0
+.recv_done
+.send_loop
inc d
- jr z, .got_zero
+ jr z, .send_done
ldh a, [c]
- bit 1, a
- jr nz, .wait_zero
-.got_zero
+ bit rRP_RECEIVING, a
+ jr nz, .send_loop
+.send_done
ldh a, [hMGPrevTIMA]
ld d, a
ldh a, [rTIMA]
@@ -895,9 +1015,9 @@ Function2a3dd:
.zero
res 0, e
.ok
- ldh a, [hPrintNumBuffer + 3]
+ ldh a, [hMGNumBits]
dec a
- ldh [hPrintNumBuffer + 3], a
+ ldh [hMGNumBits], a
jr z, .continue
ld a, e
rlca
@@ -907,34 +1027,35 @@ Function2a3dd:
.continue
ld a, e
ld [hli], a
- ldh a, [hPrintNumBuffer + 4]
+ ldh a, [hMGChecksum + 0]
add e
- ldh [hPrintNumBuffer + 4], a
- ldh a, [hPrintNumBuffer + 5]
+ ldh [hMGChecksum + 0], a
+ ldh a, [hMGChecksum + 1]
adc 0
- ldh [hPrintNumBuffer + 5], a
+ ldh [hMGChecksum + 1], a
jr .main_loop
.done
- call Function2a1a2
+ call StartFastIRTimer
xor a
ldh [rIF], a
- ld d, $0
- call Function2a1d7
- jp z, Function2a370
- ld d, $10
- call Function2a1ff
+ ld d, 0
+ call ReceiveInfraredLEDOn
+ jp z, InfraredLEDReceiveTimedOut
+
+ ld d, 16
+ call SendInfraredLEDOff
ret
-Function2a45c:
- ld b, $0
- jp Function2a2c1
+SendEmptyIRDataBlock:
+ ld b, 0
+ jp SendIRDataBlock
-Function2a461:
- ld b, $0
- jp Function2a385
+ReceiveEmptyIRDataBlock:
+ ld b, 0
+ jp ReceiveIRDataBlock
-MysteryGift_ReadJoypad:
+MysteryGift_UpdateJoypad:
; We can only get four inputs at a time.
; We take d-pad first for no particular reason.
ld a, R_DPAD
@@ -979,9 +1100,10 @@ endr
ldh [rJOYP], a
ret
-MysteryGift_CheckAndSetDecorationAlreadyReceived:
+CheckAndSetMysteryGiftDecorationAlreadyReceived:
+; Return nz if decoration c was already received; otherwise receive it.
call GetMysteryGiftBank
- ld d, $0
+ ld d, 0
ld b, CHECK_FLAG
ld hl, sMysteryGiftDecorationsReceived
lda_predef SmallFarFlagAction
@@ -1001,12 +1123,12 @@ MysteryGift_CheckAndSetDecorationAlreadyReceived:
xor a
ret
-MysteryGift_CopyReceivedDecosToPC:
+CopyMysteryGiftReceivedDecorationsToPC:
call GetMysteryGiftBank
- ld c, $0
+ ld c, 0
.loop
push bc
- ld d, $0
+ ld d, 0
ld b, CHECK_FLAG
ld hl, sMysteryGiftDecorationsReceived
predef SmallFarFlagAction
@@ -1020,57 +1142,68 @@ MysteryGift_CopyReceivedDecosToPC:
.skip
inc c
ld a, c
- cp TrophyIDs - DecorationIDs
+ cp NUM_NON_TROPHY_DECOS
jr c, .loop
jp CloseSRAM
UnlockMysteryGift:
+; If [sMysteryGiftUnlocked] was -1, this sets both
+; [sMysteryGiftUnlocked] and [sMysteryGiftItem] to 0.
call GetMysteryGiftBank
ld hl, sMysteryGiftUnlocked
ld a, [hl]
inc a
jr nz, .ok
ld [hld], a
+ assert sMysteryGiftUnlocked - 1 == sMysteryGiftItem
ld [hl], a
.ok
jp CloseSRAM
-Function2a4f6:
+ResetDailyMysteryGiftLimitIfUnlocked:
call GetMysteryGiftBank
ld a, [sNumDailyMysteryGiftPartnerIDs]
- cp $ff
- jr z, .okay
+ cp -1 ; locked?
+ jr z, .dont_clear
xor a
ld [sNumDailyMysteryGiftPartnerIDs], a
-.okay
+.dont_clear
jp CloseSRAM
BackupMysteryGift:
+; Copies [sMysteryGiftItem] to [sBackupMysteryGiftItem],
+; and [sMysteryGiftUnlocked] to [sNumDailyMysteryGiftPartnerIDs].
call GetMysteryGiftBank
ld hl, sMysteryGiftItem
ld de, sBackupMysteryGiftItem
ld a, [hli]
ld [de], a
inc de
+ assert sMysteryGiftItem + 1 == sMysteryGiftUnlocked
+ assert sBackupMysteryGiftItem + 1 == sNumDailyMysteryGiftPartnerIDs
ld a, [hl]
ld [de], a
jp CloseSRAM
RestoreMysteryGift:
+; Copies [sBackupMysteryGiftItem] to [sMysteryGiftItem],
+; and [sNumDailyMysteryGiftPartnerIDs] to [sMysteryGiftUnlocked].
call GetMysteryGiftBank
ld hl, sBackupMysteryGiftItem
ld de, sMysteryGiftItem
ld a, [hli]
ld [de], a
inc de
+ assert sBackupMysteryGiftItem + 1 == sNumDailyMysteryGiftPartnerIDs
+ assert sMysteryGiftItem + 1 == sMysteryGiftUnlocked
ld a, [hl]
ld [de], a
jp CloseSRAM
-MysteryGift_ClearTrainerData:
- ld hl, wMysteryGiftTrainerData
+ClearMysteryGiftTrainer:
+ ld hl, wMysteryGiftTrainer
xor a
- ld b, wMysteryGiftTrainerDataEnd - wMysteryGiftTrainerData
+ ld b, wMysteryGiftTrainerEnd - wMysteryGiftTrainer
.loop
ld [hli], a
dec b
@@ -1078,5 +1211,5 @@ MysteryGift_ClearTrainerData:
ret
GetMysteryGiftBank:
- ld a, BANK(sBackupMysteryGiftItem)
+ ld a, BANK(sMysteryGiftData)
jp OpenSRAM
diff --git a/engine/link/mystery_gift_2.asm b/engine/link/mystery_gift_2.asm
index 493db05c..af3715e0 100644
--- a/engine/link/mystery_gift_2.asm
+++ b/engine/link/mystery_gift_2.asm
@@ -1,24 +1,24 @@
-PrepMysteryGiftDataToSend:
+StageDataForMysteryGift:
ld de, wMysteryGiftStaging
- ld a, $1 + GS_VERSION
+ ld a, GS_VERSION + 1
ld [de], a
- inc de ; wc701
+ inc de ; wMysteryGiftStaging+1
ld a, BANK(sGameData)
call OpenSRAM
ld hl, sPlayerData + wPlayerID - wPlayerData
ld a, [hli]
ld [de], a
ld b, a
- inc de ; wc702
+ inc de ; wMysteryGiftStaging+2
ld a, [hl]
ld [de], a
ld c, a
- inc de ; wc703
+ inc de ; wMysteryGiftStaging+3
push bc
ld hl, sPlayerData + wPlayerName - wPlayerData
ld bc, NAME_LENGTH
call CopyBytes
- push de ; wc70e
+ push de ; wMysteryGiftStaging+14
ld hl, sPokemonData + wPokedexCaught - wPokemonData
ld b, wEndPokedexCaught - wPokedexCaught
call CountSetBits
@@ -26,30 +26,30 @@ PrepMysteryGiftDataToSend:
pop bc
ld a, [wNumSetBits]
ld [de], a
- inc de ; wc70f
+ inc de ; wMysteryGiftStaging+15
call CloseSRAM
call Random
and 1
ld [de], a
- inc de ; wc710
+ inc de ; wMysteryGiftStaging+16
call .RandomSample
ld [de], a
- inc de ; wc711
+ inc de ; wMysteryGiftStaging+17
ld a, c
ld c, b
ld b, a
call .RandomSample
ld [de], a
- inc de ; wc712
+ inc de ; wMysteryGiftStaging+18
ld a, BANK(sBackupMysteryGiftItem)
call OpenSRAM
ld a, [sBackupMysteryGiftItem]
ld [de], a
inc de
- ld a, [sBackupMysteryGiftItem + 1]
+ ld a, [sNumDailyMysteryGiftPartnerIDs]
ld [de], a
- ld a, $14
- ld [wc900], a
+ ld a, wMysteryGiftPlayerDataEnd - wMysteryGiftPlayerData
+ ld [wUnusedMysteryGiftStagedDataLength], a
call CloseSRAM
ld hl, wMysteryGiftStaging
ld de, wMysteryGiftPlayerData
@@ -121,7 +121,7 @@ PrepMysteryGiftDataToSend:
pop de
ret
-MysteryGiftGetItemHeldEffect:
+MysteryGiftGetItem:
ld a, c
cp MysteryGiftItems.End - MysteryGiftItems
jr nc, MysteryGiftFallbackItem
diff --git a/engine/link/mystery_gift_3.asm b/engine/link/mystery_gift_3.asm
index bc12d9c8..4a8d92c4 100644
--- a/engine/link/mystery_gift_3.asm
+++ b/engine/link/mystery_gift_3.asm
@@ -45,8 +45,8 @@ StagePartyDataForMysteryGift:
.party_end
ld a, -1
ld [de], a
- ld a, $26
- ld [wc900], a
+ ld a, wMysteryGiftTrainerEnd - wMysteryGiftTrainer
+ ld [wUnusedMysteryGiftStagedDataLength], a
jp CloseSRAM
InitMysteryGiftLayout:
diff --git a/engine/link/time_capsule.asm b/engine/link/time_capsule.asm
index 158e7ec9..3c1cfb5f 100644
--- a/engine/link/time_capsule.asm
+++ b/engine/link/time_capsule.asm
@@ -1,11 +1,11 @@
; These functions seem to be related to backwards compatibility
ValidateOTTrademon:
- ld a, [wceee]
+ ld a, [wCurOTTradePartyMon]
ld hl, wOTPartyMon1Species
call GetPartyLocation
push hl
- ld a, [wceee]
+ ld a, [wCurOTTradePartyMon]
inc a
ld c, a
ld b, 0
@@ -30,7 +30,7 @@ ValidateOTTrademon:
cp LINK_TIMECAPSULE
jr nz, .normal
ld hl, wOTPartySpecies
- ld a, [wceee]
+ ld a, [wCurOTTradePartyMon]
ld c, a
ld b, 0
add hl, bc
@@ -65,11 +65,11 @@ ValidateOTTrademon:
ret
CheckAnyOtherAliveMonsForTrade:
- ld a, [wceed]
+ ld a, [wCurTradePartyMon]
ld d, a
ld a, [wPartyCount]
ld b, a
- ld c, $0
+ ld c, 0
.loop
ld a, c
cp d
@@ -87,7 +87,7 @@ CheckAnyOtherAliveMonsForTrade:
inc c
dec b
jr nz, .loop
- ld a, [wceee]
+ ld a, [wCurOTTradePartyMon]
ld hl, wOTPartyMon1HP
call GetPartyLocation
ld a, [hli]