Add subdirectories to engine/ similar to pokecrystal

This commit is contained in:
Rangi 2020-07-02 23:30:21 -04:00
parent 5559d51c86
commit f275790aec
124 changed files with 342 additions and 346 deletions

View file

@ -1,151 +0,0 @@
CableClubNPC::
ld hl, CableClubNPCWelcomeText
call PrintText
CheckEvent EVENT_GOT_POKEDEX
jp nz, .receivedPokedex
; if the player hasn't received the pokedex
ld c, 60
call DelayFrames
ld hl, CableClubNPCMakingPreparationsText
call PrintText
jp .didNotConnect
.receivedPokedex
ld a, $1
ld [wMenuJoypadPollCount], a
ld a, 90
ld [wLinkTimeoutCounter], a
.establishConnectionLoop
ld a, [hSerialConnectionStatus]
cp USING_INTERNAL_CLOCK
jr z, .establishedConnection
cp USING_EXTERNAL_CLOCK
jr z, .establishedConnection
ld a, CONNECTION_NOT_ESTABLISHED
ld [hSerialConnectionStatus], a
ld a, ESTABLISH_CONNECTION_WITH_EXTERNAL_CLOCK
ld [rSB], a
xor a
ld [hSerialReceiveData], a
ld a, START_TRANSFER_EXTERNAL_CLOCK
ld [rSC], a
ld a, [wLinkTimeoutCounter]
dec a
ld [wLinkTimeoutCounter], a
jr z, .failedToEstablishConnection
ld a, ESTABLISH_CONNECTION_WITH_INTERNAL_CLOCK
ld [rSB], a
ld a, START_TRANSFER_INTERNAL_CLOCK
ld [rSC], a
call DelayFrame
jr .establishConnectionLoop
.establishedConnection
call Serial_SendZeroByte
call DelayFrame
call Serial_SendZeroByte
ld c, 50
call DelayFrames
ld hl, CableClubNPCPleaseApplyHereHaveToSaveText
call PrintText
xor a
ld [wMenuJoypadPollCount], a
call YesNoChoice
ld a, $1
ld [wMenuJoypadPollCount], a
ld a, [wCurrentMenuItem]
and a
jr nz, .choseNo
callab SaveSAVtoSRAM
call WaitForSoundToFinish
ld a, SFX_SAVE
call PlaySoundWaitForCurrent
ld hl, CableClubNPCPleaseWaitText
call PrintText
ld hl, wUnknownSerialCounter
ld a, $3
ld [hli], a
xor a
ld [hl], a
ld [hSerialReceivedNewData], a
ld [wSerialExchangeNybbleSendData], a
call Serial_SyncAndExchangeNybble
ld hl, wUnknownSerialCounter
ld a, [hli]
inc a
jr nz, .connected
ld a, [hl]
inc a
jr nz, .connected
ld b, 10
.syncLoop
call DelayFrame
call Serial_SendZeroByte
dec b
jr nz, .syncLoop
call CloseLinkConnection
ld hl, CableClubNPCLinkClosedBecauseOfInactivityText
call PrintText
jr .didNotConnect
.failedToEstablishConnection
ld hl, CableClubNPCAreaReservedFor2FriendsLinkedByCableText
call PrintText
jr .didNotConnect
.choseNo
call CloseLinkConnection
ld hl, CableClubNPCPleaseComeAgainText
call PrintText
.didNotConnect
xor a
ld hl, wUnknownSerialCounter
ld [hli], a
ld [hl], a
ld hl, wd72e
res 6, [hl]
xor a
ld [wMenuJoypadPollCount], a
ret
.connected
xor a
ld [hld], a
ld [hl], a
jpab LinkMenu
CableClubNPCAreaReservedFor2FriendsLinkedByCableText:
TX_FAR _CableClubNPCAreaReservedFor2FriendsLinkedByCableText
db "@"
CableClubNPCWelcomeText:
TX_FAR _CableClubNPCWelcomeText
db "@"
CableClubNPCPleaseApplyHereHaveToSaveText:
TX_FAR _CableClubNPCPleaseApplyHereHaveToSaveText
db "@"
CableClubNPCPleaseWaitText:
TX_FAR _CableClubNPCPleaseWaitText
TX_DELAY
db "@"
CableClubNPCLinkClosedBecauseOfInactivityText:
TX_FAR _CableClubNPCLinkClosedBecauseOfInactivityText
db "@"
CableClubNPCPleaseComeAgainText:
TX_FAR _CableClubNPCPleaseComeAgainText
db "@"
CableClubNPCMakingPreparationsText:
TX_FAR _CableClubNPCMakingPreparationsText
db "@"
CloseLinkConnection:
call Delay3
ld a, CONNECTION_NOT_ESTABLISHED
ld [hSerialConnectionStatus], a
ld a, ESTABLISH_CONNECTION_WITH_EXTERNAL_CLOCK
ld [rSB], a
xor a
ld [hSerialReceiveData], a
ld a, START_TRANSFER_EXTERNAL_CLOCK
ld [rSC], a
ret

View file

@ -1,112 +0,0 @@
PrintCardKeyText:
ld hl, SilphCoMapList
ld a, [wCurMap]
ld b, a
.silphCoMapListLoop
ld a, [hli]
cp $ff
ret z
cp b
jr nz, .silphCoMapListLoop
predef GetTileAndCoordsInFrontOfPlayer
ld a, [wTileInFrontOfPlayer]
cp $18
jr z, .cardKeyDoorInFrontOfPlayer
cp $24
jr z, .cardKeyDoorInFrontOfPlayer
ld b, a
ld a, [wCurMap]
cp SILPH_CO_11F
ret nz
ld a, b
cp $5e
ret nz
.cardKeyDoorInFrontOfPlayer
ld b, CARD_KEY
call IsItemInBag
jr z, .noCardKey
call GetCoordsInFrontOfPlayer
push de
tx_pre_id CardKeySuccessText
ld [hSpriteIndexOrTextID], a
call PrintPredefTextID
pop de
srl d
ld a, d
ld b, a
ld [wCardKeyDoorY], a
srl e
ld a, e
ld c, a
ld [wCardKeyDoorX], a
ld a, [wCurMap]
cp SILPH_CO_11F
jr nz, .notSilphCo11F
ld a, $3
jr .replaceCardKeyDoorTileBlock
.notSilphCo11F
ld a, $e
.replaceCardKeyDoorTileBlock
ld [wNewTileBlockID], a
predef ReplaceTileBlock
ld hl, wCurrentMapScriptFlags
set 5, [hl]
ld a, SFX_GO_INSIDE
jp PlaySound
.noCardKey
tx_pre_id CardKeyFailText
ld [hSpriteIndexOrTextID], a
jp PrintPredefTextID
SilphCoMapList:
db SILPH_CO_2F
db SILPH_CO_3F
db SILPH_CO_4F
db SILPH_CO_5F
db SILPH_CO_6F
db SILPH_CO_7F
db SILPH_CO_8F
db SILPH_CO_9F
db SILPH_CO_10F
db SILPH_CO_11F
db $FF
CardKeySuccessText::
TX_FAR _CardKeySuccessText1
TX_SFX_ITEM_1
TX_FAR _CardKeySuccessText2
db "@"
CardKeyFailText::
TX_FAR _CardKeyFailText
db "@"
; d = Y
; e = X
GetCoordsInFrontOfPlayer:
ld a, [wYCoord]
ld d, a
ld a, [wXCoord]
ld e, a
ld a, [wSpriteStateData1 + 9] ; player's sprite facing direction
and a
jr nz, .notFacingDown
; facing down
inc d
ret
.notFacingDown
cp SPRITE_FACING_UP
jr nz, .notFacingUp
; facing up
dec d
ret
.notFacingUp
cp SPRITE_FACING_LEFT
jr nz, .notFacingLeft
; facing left
dec e
ret
.notFacingLeft
; facing right
inc e
ret

View file

@ -1,123 +0,0 @@
GiveFossilToCinnabarLab::
ld hl, wd730
set 6, [hl]
xor a
ld [wCurrentMenuItem], a
ld a, A_BUTTON | B_BUTTON
ld [wMenuWatchedKeys], a
ld a, [wFilteredBagItemsCount]
dec a
ld [wMaxMenuItem], a
ld a, 2
ld [wTopMenuItemY], a
ld a, 1
ld [wTopMenuItemX], a
ld a, [wFilteredBagItemsCount]
dec a
ld bc, 2
ld hl, 3
call AddNTimes
dec l
ld b, l
ld c, $d
coord hl, 0, 0
call TextBoxBorder
call UpdateSprites
call PrintFossilsInBag
ld hl, wd730
res 6, [hl]
call HandleMenuInput
bit 1, a ; pressed B?
jr nz, .cancelledGivingFossil
ld hl, wFilteredBagItems
ld a, [wCurrentMenuItem]
ld d, 0
ld e, a
add hl, de
ld a, [hl]
ld [$ffdb], a
cp DOME_FOSSIL
jr z, .choseDomeFossil
cp HELIX_FOSSIL
jr z, .choseHelixFossil
ld b, AERODACTYL
jr .fossilSelected
.choseHelixFossil
ld b, OMANYTE
jr .fossilSelected
.choseDomeFossil
ld b, KABUTO
.fossilSelected
ld [wFossilItem], a
ld a, b
ld [wFossilMon], a
call LoadFossilItemAndMonName
ld hl, LabFossil_610ae
call PrintText
call YesNoChoice
ld a, [wCurrentMenuItem]
and a
jr nz, .cancelledGivingFossil
ld hl, LabFossil_610b3
call PrintText
ld a, [wFossilItem]
ld [hItemToRemoveID], a
callba RemoveItemByID
ld hl, LabFossil_610b8
call PrintText
SetEvents EVENT_GAVE_FOSSIL_TO_LAB, EVENT_LAB_STILL_REVIVING_FOSSIL
ret
.cancelledGivingFossil
ld hl, LabFossil_610bd
call PrintText
ret
LabFossil_610ae:
TX_FAR _Lab4Text_610ae
db "@"
LabFossil_610b3:
TX_FAR _Lab4Text_610b3
db "@"
LabFossil_610b8:
TX_FAR _Lab4Text_610b8
db "@"
LabFossil_610bd:
TX_FAR _Lab4Text_610bd
db "@"
PrintFossilsInBag:
; Prints each fossil in the player's bag on a separate line in the menu.
ld hl, wFilteredBagItems
xor a
ld [hItemCounter], a
.loop
ld a, [hli]
cp $ff
ret z
push hl
ld [wd11e], a
call GetItemName
coord hl, 2, 2
ld a, [hItemCounter]
ld bc, SCREEN_WIDTH * 2
call AddNTimes
ld de, wcd6d
call PlaceString
ld hl, hItemCounter
inc [hl]
pop hl
jr .loop
; loads the names of the fossil item and the resulting mon
LoadFossilItemAndMonName::
ld a, [wFossilMon]
ld [wd11e], a
call GetMonName
call CopyStringToCF4B
ld a, [wFossilItem]
ld [wd11e], a
call GetItemName
ret

View file

@ -1,161 +0,0 @@
HiddenItems:
ld hl, HiddenItemCoords
call FindHiddenItemOrCoinsIndex
ld [wHiddenItemOrCoinsIndex], a
ld hl, wObtainedHiddenItemsFlags
ld a, [wHiddenItemOrCoinsIndex]
ld c, a
ld b, FLAG_TEST
predef FlagActionPredef
ld a, c
and a
ret nz
call EnableAutoTextBoxDrawing
ld a, 1
ld [wDoNotWaitForButtonPressAfterDisplayingText], a
ld a, [wHiddenObjectFunctionArgument] ; item ID
ld [wd11e], a
call GetItemName
tx_pre_jump FoundHiddenItemText
INCLUDE "data/hidden_item_coords.asm"
FoundHiddenItemText::
TX_FAR _FoundHiddenItemText
TX_ASM
ld a, [wHiddenObjectFunctionArgument] ; item ID
ld b, a
ld c, 1
call GiveItem
jr nc, .bagFull
ld hl, wObtainedHiddenItemsFlags
ld a, [wHiddenItemOrCoinsIndex]
ld c, a
ld b, FLAG_SET
predef FlagActionPredef
ld a, SFX_GET_ITEM_2
call PlaySoundWaitForCurrent
call WaitForSoundToFinish
jp TextScriptEnd
.bagFull
call WaitForTextScrollButtonPress ; wait for button press
xor a
ld [wDoNotWaitForButtonPressAfterDisplayingText], a
ld hl, HiddenItemBagFullText
call PrintText
jp TextScriptEnd
HiddenItemBagFullText::
TX_FAR _HiddenItemBagFullText
db "@"
HiddenCoins:
ld b, COIN_CASE
predef GetQuantityOfItemInBag
ld a, b
and a
ret z
ld hl, HiddenCoinCoords
call FindHiddenItemOrCoinsIndex
ld [wHiddenItemOrCoinsIndex], a
ld hl, wObtainedHiddenCoinsFlags
ld a, [wHiddenItemOrCoinsIndex]
ld c, a
ld b, FLAG_TEST
predef FlagActionPredef
ld a, c
and a
ret nz
xor a
ld [hUnusedCoinsByte], a
ld [hCoins], a
ld [hCoins + 1], a
ld a, [wHiddenObjectFunctionArgument]
sub COIN
cp 10
jr z, .bcd10
cp 20
jr z, .bcd20
cp 40
jr z, .bcd20 ; should be bcd40
jr .bcd100
.bcd10
ld a, $10
ld [hCoins + 1], a
jr .bcdDone
.bcd20
ld a, $20
ld [hCoins + 1], a
jr .bcdDone
.bcd40 ; due to a typo, this is never used
ld a, $40
ld [hCoins + 1], a
jr .bcdDone
.bcd100
ld a, $1
ld [hCoins], a
.bcdDone
ld de, wPlayerCoins + 1
ld hl, hCoins + 1
ld c, $2
predef AddBCDPredef
ld hl, wObtainedHiddenCoinsFlags
ld a, [wHiddenItemOrCoinsIndex]
ld c, a
ld b, FLAG_SET
predef FlagActionPredef
call EnableAutoTextBoxDrawing
ld a, [wPlayerCoins]
cp $99
jr nz, .roomInCoinCase
ld a, [wPlayerCoins + 1]
cp $99
jr nz, .roomInCoinCase
tx_pre_id DroppedHiddenCoinsText
jr .done
.roomInCoinCase
tx_pre_id FoundHiddenCoinsText
.done
jp PrintPredefTextID
INCLUDE "data/hidden_coins.asm"
FoundHiddenCoinsText::
TX_FAR _FoundHiddenCoinsText
TX_SFX_ITEM_2
db "@"
DroppedHiddenCoinsText::
TX_FAR _FoundHiddenCoins2Text
TX_SFX_ITEM_2
TX_FAR _DroppedHiddenCoinsText
db "@"
FindHiddenItemOrCoinsIndex:
ld a, [wHiddenObjectY]
ld d, a
ld a, [wHiddenObjectX]
ld e, a
ld a, [wCurMap]
ld b, a
ld c, -1
.loop
inc c
ld a, [hli]
cp $ff ; end of the list?
ret z ; if so, we're done here
cp b
jr nz, .next1
ld a, [hli]
cp d
jr nz, .next2
ld a, [hli]
cp e
jr nz, .loop
ld a, c
ret
.next1
inc hl
.next2
inc hl
jr .loop

View file

@ -1,54 +0,0 @@
PickUpItem:
call EnableAutoTextBoxDrawing
ld a, [hSpriteIndexOrTextID]
ld b, a
ld hl, wMissableObjectList
.missableObjectsListLoop
ld a, [hli]
cp $ff
ret z
cp b
jr z, .isMissable
inc hl
jr .missableObjectsListLoop
.isMissable
ld a, [hl]
ld [$ffdb], a
ld hl, wMapSpriteExtraData
ld a, [hSpriteIndexOrTextID]
dec a
add a
ld d, 0
ld e, a
add hl, de
ld a, [hl]
ld b, a ; item
ld c, 1 ; quantity
call GiveItem
jr nc, .BagFull
ld a, [$ffdb]
ld [wMissableObjectIndex], a
predef HideObject
ld a, 1
ld [wDoNotWaitForButtonPressAfterDisplayingText], a
ld hl, FoundItemText
jr .print
.BagFull
ld hl, NoMoreRoomForItemText
.print
call PrintText
ret
FoundItemText:
TX_FAR _FoundItemText
TX_SFX_ITEM_1
db "@"
NoMoreRoomForItemText:
TX_FAR _NoMoreRoomForItemText
db "@"

View file

@ -1,71 +0,0 @@
OaksAideScript:
ld hl, OaksAideHiText
call PrintText
call YesNoChoice
ld a, [wCurrentMenuItem]
and a
jr nz, .choseNo
ld hl, wPokedexOwned
ld b, wPokedexOwnedEnd - wPokedexOwned
call CountSetBits
ld a, [wNumSetBits]
ld [hOaksAideNumMonsOwned], a
ld b, a
ld a, [hOaksAideRequirement]
cp b
jr z, .giveItem
jr nc, .notEnoughOwnedMons
.giveItem
ld hl, OaksAideHereYouGoText
call PrintText
ld a, [hOaksAideRewardItem]
ld b, a
ld c, 1
call GiveItem
jr nc, .bagFull
ld hl, OaksAideGotItemText
call PrintText
ld a, $1
jr .done
.bagFull
ld hl, OaksAideNoRoomText
call PrintText
xor a
jr .done
.notEnoughOwnedMons
ld hl, OaksAideUhOhText
call PrintText
ld a, $80
jr .done
.choseNo
ld hl, OaksAideComeBackText
call PrintText
ld a, $ff
.done
ld [hOaksAideResult], a
ret
OaksAideHiText:
TX_FAR _OaksAideHiText
db "@"
OaksAideUhOhText:
TX_FAR _OaksAideUhOhText
db "@"
OaksAideComeBackText:
TX_FAR _OaksAideComeBackText
db "@"
OaksAideHereYouGoText:
TX_FAR _OaksAideHereYouGoText
db "@"
OaksAideGotItemText:
TX_FAR _OaksAideGotItemText
TX_SFX_ITEM_1
db "@"
OaksAideNoRoomText:
TX_FAR _OaksAideNoRoomText
db "@"

View file

@ -1,189 +0,0 @@
PrepareOAMData::
; Determine OAM data for currently visible
; sprites and write it to wOAMBuffer.
ld a, [wUpdateSpritesEnabled]
dec a
jr z, .updateEnabled
cp -1
ret nz
ld [wUpdateSpritesEnabled], a
jp HideSprites
.updateEnabled
xor a
ld [hOAMBufferOffset], a
.spriteLoop
ld [hSpriteOffset2], a
ld d, wSpriteStateData1 / $100
ld a, [hSpriteOffset2]
ld e, a
ld a, [de] ; c1x0
and a
jp z, .nextSprite
inc e
inc e
ld a, [de] ; c1x2 (facing/anim)
ld [wd5cd], a
cp $ff ; off-screen (don't draw)
jr nz, .visible
call GetSpriteScreenXY
jr .nextSprite
.visible
cp $a0 ; is the sprite unchanging like an item ball or boulder?
jr c, .usefacing
; unchanging
and $f
add $10 ; skip to the second half of the table which doesn't account for facing direction
jr .next
.usefacing
and $f
.next
ld l, a
; get sprite priority
push de
inc d
ld a, e
add $5
ld e, a
ld a, [de] ; c2x7
and $80
ld [hSpritePriority], a ; temp store sprite priority
pop de
; read the entry from the table
ld h, 0
ld bc, SpriteFacingAndAnimationTable
add hl, hl
add hl, hl
add hl, bc
ld a, [hli]
ld c, a
ld a, [hli]
ld b, a
ld a, [hli]
ld h, [hl]
ld l, a
call GetSpriteScreenXY
ld a, [hOAMBufferOffset]
ld e, a
ld d, wOAMBuffer / $100
.tileLoop
ld a, [hSpriteScreenY] ; temp for sprite Y position
add $10 ; Y=16 is top of screen (Y=0 is invisible)
add [hl] ; add Y offset from table
ld [de], a ; write new sprite OAM Y position
inc hl
ld a, [hSpriteScreenX] ; temp for sprite X position
add $8 ; X=8 is left of screen (X=0 is invisible)
add [hl] ; add X offset from table
inc e
ld [de], a ; write new sprite OAM X position
inc e
ld a, [bc] ; read pattern number offset (accommodates orientation (offset 0,4 or 8) and animation (offset 0 or $80))
inc bc
push bc
ld b, a
ld a, [wd5cd] ; temp copy of c1x2
swap a ; high nybble determines sprite used (0 is always player sprite, next are some npcs)
and $f
; Sprites $a and $b have one face (and therefore 4 tiles instead of 12).
; As a result, sprite $b's tile offset is less than normal.
cp $b
jr nz, .notFourTileSprite
ld a, $a * 12 + 4
jr .next2
.notFourTileSprite
; a *= 12
sla a
sla a
ld c, a
sla a
add c
.next2
add b ; add the tile offset from the table (based on frame and facing direction)
pop bc
ld [de], a ; tile id
inc hl
inc e
ld a, [hl]
bit 1, a ; is the tile allowed to set the sprite priority bit?
jr z, .skipPriority
ld a, [hSpritePriority]
or [hl]
.skipPriority
inc hl
ld [de], a
inc e
bit 0, a ; OAMFLAG_ENDOFDATA
jr z, .tileLoop
ld a, e
ld [hOAMBufferOffset], a
.nextSprite
ld a, [hSpriteOffset2]
add $10
cp $100 % $100
jp nz, .spriteLoop
; Clear unused OAM.
ld a, [hOAMBufferOffset]
ld l, a
ld h, wOAMBuffer / $100
ld de, $4
ld b, $a0
ld a, [wd736]
bit 6, a ; jumping down ledge or fishing animation?
ld a, $a0
jr z, .clear
; Don't clear the last 4 entries because they are used for the shadow in the
; jumping down ledge animation and the rod in the fishing animation.
ld a, $90
.clear
cp l
ret z
ld [hl], b
add hl, de
jr .clear
GetSpriteScreenXY:
inc e
inc e
ld a, [de] ; c1x4
ld [hSpriteScreenY], a
inc e
inc e
ld a, [de] ; c1x6
ld [hSpriteScreenX], a
ld a, 4
add e
ld e, a
ld a, [hSpriteScreenY]
add 4
and $f0
ld [de], a ; c1xa (y)
inc e
ld a, [hSpriteScreenX]
and $f0
ld [de], a ; c1xb (x)
ret

View file

@ -0,0 +1,201 @@
FindPathToPlayer:
xor a
ld hl, hFindPathNumSteps
ld [hli], a ; hFindPathNumSteps
ld [hli], a ; hFindPathFlags
ld [hli], a ; hFindPathYProgress
ld [hl], a ; hFindPathXProgress
ld hl, wNPCMovementDirections2
ld de, $0
.loop
ld a, [hFindPathYProgress]
ld b, a
ld a, [hNPCPlayerYDistance] ; Y distance in steps
call CalcDifference
ld d, a
and a
jr nz, .asm_f8da
ld a, [hFindPathFlags]
set 0, a ; current end of path matches the player's Y coordinate
ld [hFindPathFlags], a
.asm_f8da
ld a, [hFindPathXProgress]
ld b, a
ld a, [hNPCPlayerXDistance] ; X distance in steps
call CalcDifference
ld e, a
and a
jr nz, .asm_f8ec
ld a, [hFindPathFlags]
set 1, a ; current end of path matches the player's X coordinate
ld [hFindPathFlags], a
.asm_f8ec
ld a, [hFindPathFlags]
cp $3 ; has the end of the path reached the player's position?
jr z, .done
; Compare whether the X distance between the player and the current of the path
; is greater or if the Y distance is. Then, try to reduce whichever is greater.
ld a, e
cp d
jr c, .yDistanceGreater
; x distance is greater
ld a, [hNPCPlayerRelativePosFlags]
bit 1, a
jr nz, .playerIsLeftOfNPC
ld d, NPC_MOVEMENT_RIGHT
jr .next1
.playerIsLeftOfNPC
ld d, NPC_MOVEMENT_LEFT
.next1
ld a, [hFindPathXProgress]
add 1
ld [hFindPathXProgress], a
jr .storeDirection
.yDistanceGreater
ld a, [hNPCPlayerRelativePosFlags]
bit 0, a
jr nz, .playerIsAboveNPC
ld d, NPC_MOVEMENT_DOWN
jr .next2
.playerIsAboveNPC
ld d, NPC_MOVEMENT_UP
.next2
ld a, [hFindPathYProgress]
add 1
ld [hFindPathYProgress], a
.storeDirection
ld a, d
ld [hli], a
ld a, [hFindPathNumSteps]
inc a
ld [hFindPathNumSteps], a
jp .loop
.done
ld [hl], $ff
ret
CalcPositionOfPlayerRelativeToNPC:
xor a
ld [hNPCPlayerRelativePosFlags], a
ld a, [wSpriteStateData1 + 4] ; player's sprite screen Y position in pixels
ld d, a
ld a, [wSpriteStateData1 + 6] ; player's sprite screen X position in pixels
ld e, a
ld hl, wSpriteStateData1
ld a, [hNPCSpriteOffset]
add l
add $4
ld l, a
jr nc, .noCarry
inc h
.noCarry
ld a, d
ld b, a
ld a, [hli] ; NPC sprite screen Y position in pixels
call CalcDifference
jr nc, .NPCSouthOfOrAlignedWithPlayer
.NPCNorthOfPlayer
push hl
ld hl, hNPCPlayerRelativePosFlags
bit 0, [hl]
set 0, [hl]
pop hl
jr .divideYDistance
.NPCSouthOfOrAlignedWithPlayer
push hl
ld hl, hNPCPlayerRelativePosFlags
bit 0, [hl]
res 0, [hl]
pop hl
.divideYDistance
push hl
ld hl, hDividend2
ld [hli], a
ld a, 16
ld [hli], a
call DivideBytes ; divide Y absolute distance by 16
ld a, [hl] ; quotient
ld [hNPCPlayerYDistance], a
pop hl
inc hl
ld b, e
ld a, [hl] ; NPC sprite screen X position in pixels
call CalcDifference
jr nc, .NPCEastOfOrAlignedWithPlayer
.NPCWestOfPlayer
push hl
ld hl, hNPCPlayerRelativePosFlags
bit 1, [hl]
set 1, [hl]
pop hl
jr .divideXDistance
.NPCEastOfOrAlignedWithPlayer
push hl
ld hl, hNPCPlayerRelativePosFlags
bit 1, [hl]
res 1, [hl]
pop hl
.divideXDistance
ld [hDividend2], a
ld a, 16
ld [hDivisor2], a
call DivideBytes ; divide X absolute distance by 16
ld a, [hQuotient2]
ld [hNPCPlayerXDistance], a
ld a, [hNPCPlayerRelativePosPerspective]
and a
ret z
ld a, [hNPCPlayerRelativePosFlags]
cpl
and $3
ld [hNPCPlayerRelativePosFlags], a
ret
ConvertNPCMovementDirectionsToJoypadMasks:
ld a, [hNPCMovementDirections2Index]
ld [wNPCMovementDirections2Index], a
dec a
ld de, wSimulatedJoypadStatesEnd
ld hl, wNPCMovementDirections2
add l
ld l, a
jr nc, .loop
inc h
.loop
ld a, [hld]
call ConvertNPCMovementDirectionToJoypadMask
ld [de], a
inc de
ld a, [hNPCMovementDirections2Index]
dec a
ld [hNPCMovementDirections2Index], a
jr nz, .loop
ret
ConvertNPCMovementDirectionToJoypadMask:
push hl
ld b, a
ld hl, NPCMovementDirectionsToJoypadMasksTable
.loop
ld a, [hli]
cp $ff
jr z, .done
cp b
jr z, .loadJoypadMask
inc hl
jr .loop
.loadJoypadMask
ld a, [hl]
.done
pop hl
ret
NPCMovementDirectionsToJoypadMasksTable:
db NPC_MOVEMENT_UP, D_UP
db NPC_MOVEMENT_DOWN, D_DOWN
db NPC_MOVEMENT_LEFT, D_LEFT
db NPC_MOVEMENT_RIGHT, D_RIGHT
db $ff
; unreferenced
ret

View file

@ -1,102 +0,0 @@
PewterGuys:
ld hl, wSimulatedJoypadStatesEnd
ld a, [wSimulatedJoypadStatesIndex]
dec a ; this decrement causes it to overwrite the last byte before $FF in the list
ld [wSimulatedJoypadStatesIndex], a
ld d, 0
ld e, a
add hl, de
ld d, h
ld e, l
ld hl, PointerTable_37ce6
ld a, [wWhichPewterGuy]
add a
ld b, 0
ld c, a
add hl, bc
ld a, [hli]
ld h, [hl]
ld l, a
ld a, [wYCoord]
ld b, a
ld a, [wXCoord]
ld c, a
.findMatchingCoordsLoop
ld a, [hli]
cp b
jr nz, .nextEntry1
ld a, [hli]
cp c
jr nz, .nextEntry2
ld a, [hli]
ld h, [hl]
ld l, a
.copyMovementDataLoop
ld a, [hli]
cp $ff
ret z
ld [de], a
inc de
ld a, [wSimulatedJoypadStatesIndex]
inc a
ld [wSimulatedJoypadStatesIndex], a
jr .copyMovementDataLoop
.nextEntry1
inc hl
.nextEntry2
inc hl
inc hl
jr .findMatchingCoordsLoop
PointerTable_37ce6:
dw PewterMuseumGuyCoords
dw PewterGymGuyCoords
; these are the four coordinates of the spaces below, above, to the left and
; to the right of the museum guy, and pointers to different movements for
; the player to make to get positioned before the main movement.
PewterMuseumGuyCoords:
db 18, 27
dw .down
db 16, 27
dw .up
db 17, 26
dw .left
db 17, 28
dw .right
.down
db D_UP, D_UP, $ff
.up
db D_RIGHT, D_LEFT, $ff
.left
db D_UP, D_RIGHT, $ff
.right
db D_UP, D_LEFT, $ff
; these are the five coordinates which trigger the gym guy and pointers to
; different movements for the player to make to get positioned before the
; main movement
; $00 is a pause
PewterGymGuyCoords:
db 16, 34
dw .one
db 17, 35
dw .two
db 18, 37
dw .three
db 19, 37
dw .four
db 17, 36
dw .five
.one
db D_LEFT, D_DOWN, D_DOWN, D_RIGHT, $ff
.two
db D_LEFT, D_DOWN, D_RIGHT, D_LEFT, $ff
.three
db D_LEFT, D_LEFT, D_LEFT, $00, $00, $00, $00, $00, $00, $00, $00, $ff
.four
db D_LEFT, D_LEFT, D_UP, D_LEFT, $ff
.five
db D_LEFT, D_DOWN, D_LEFT, $00, $00, $00, $00, $00, $00, $00, $00, $ff

View file

@ -1,112 +0,0 @@
ApplyOutOfBattlePoisonDamage:
ld a, [wd730]
add a
jp c, .noBlackOut ; no black out if joypad states are being simulated
ld a, [wPartyCount]
and a
jp z, .noBlackOut
call IncrementDayCareMonExp
ld a, [wStepCounter]
and $3 ; is the counter a multiple of 4?
jp nz, .noBlackOut ; only apply poison damage every fourth step
ld [wWhichPokemon], a
ld hl, wPartyMon1Status
ld de, wPartySpecies
.applyDamageLoop
ld a, [hl]
and (1 << PSN)
jr z, .nextMon2 ; not poisoned
dec hl
dec hl
ld a, [hld]
ld b, a
ld a, [hli]
or b
jr z, .nextMon ; already fainted
; subtract 1 from HP
ld a, [hl]
dec a
ld [hld], a
inc a
jr nz, .noBorrow
; borrow 1 from upper byte of HP
dec [hl]
inc hl
jr .nextMon
.noBorrow
ld a, [hli]
or [hl]
jr nz, .nextMon ; didn't faint from damage
; the mon fainted from the damage
push hl
inc hl
inc hl
ld [hl], a
ld a, [de]
ld [wd11e], a
push de
ld a, [wWhichPokemon]
ld hl, wPartyMonNicks
call GetPartyMonName
xor a
ld [wJoyIgnore], a
call EnableAutoTextBoxDrawing
ld a, TEXT_MON_FAINTED
ld [hSpriteIndexOrTextID], a
call DisplayTextID
pop de
pop hl
.nextMon
inc hl
inc hl
.nextMon2
inc de
ld a, [de]
inc a
jr z, .applyDamageLoopDone
ld bc, wPartyMon2 - wPartyMon1
add hl, bc
push hl
ld hl, wWhichPokemon
inc [hl]
pop hl
jr .applyDamageLoop
.applyDamageLoopDone
ld hl, wPartyMon1Status
ld a, [wPartyCount]
ld d, a
ld e, 0
.countPoisonedLoop
ld a, [hl]
and (1 << PSN)
or e
ld e, a
ld bc, wPartyMon2 - wPartyMon1
add hl, bc
dec d
jr nz, .countPoisonedLoop
ld a, e
and a ; are any party members poisoned?
jr z, .skipPoisonEffectAndSound
ld b, $2
predef ChangeBGPalColor0_4Frames ; change BG white to dark grey for 4 frames
ld a, SFX_POISONED
call PlaySound
.skipPoisonEffectAndSound
predef AnyPartyAlive
ld a, d
and a
jr nz, .noBlackOut
call EnableAutoTextBoxDrawing
ld a, TEXT_BLACKED_OUT
ld [hSpriteIndexOrTextID], a
call DisplayTextID
ld hl, wd72e
set 5, [hl]
ld a, $ff
jr .done
.noBlackOut
xor a
.done
ld [wOutOfBattleBlackout], a
ret

View file

@ -1,68 +0,0 @@
DisplayPokemonCenterDialogue_::
call SaveScreenTilesToBuffer1 ; save screen
ld hl, PokemonCenterWelcomeText
call PrintText
ld hl, wd72e
bit 2, [hl]
set 1, [hl]
set 2, [hl]
jr nz, .skipShallWeHealYourPokemon
ld hl, ShallWeHealYourPokemonText
call PrintText
.skipShallWeHealYourPokemon
call YesNoChoicePokeCenter ; yes/no menu
ld a, [wCurrentMenuItem]
and a
jr nz, .declinedHealing ; if the player chose No
call SetLastBlackoutMap
call LoadScreenTilesFromBuffer1 ; restore screen
ld hl, NeedYourPokemonText
call PrintText
ld a, $18
ld [wSpriteStateData1 + $12], a ; make the nurse turn to face the machine
call Delay3
predef HealParty
callba AnimateHealingMachine ; do the healing machine animation
xor a
ld [wAudioFadeOutControl], a
ld a, [wAudioSavedROMBank]
ld [wAudioROMBank], a
ld a, [wMapMusicSoundID]
ld [wLastMusicSoundID], a
ld [wNewSoundID], a
call PlaySound
ld hl, PokemonFightingFitText
call PrintText
ld a, $14
ld [wSpriteStateData1 + $12], a ; make the nurse bow
ld c, a
call DelayFrames
jr .done
.declinedHealing
call LoadScreenTilesFromBuffer1 ; restore screen
.done
ld hl, PokemonCenterFarewellText
call PrintText
jp UpdateSprites
PokemonCenterWelcomeText:
TX_FAR _PokemonCenterWelcomeText
db "@"
ShallWeHealYourPokemonText:
TX_DELAY
TX_FAR _ShallWeHealYourPokemonText
db "@"
NeedYourPokemonText:
TX_FAR _NeedYourPokemonText
db "@"
PokemonFightingFitText:
TX_FAR _PokemonFightingFitText
db "@"
PokemonCenterFarewellText:
TX_DELAY
TX_FAR _PokemonCenterFarewellText
db "@"

View file

@ -1,272 +0,0 @@
DisplayPokemartDialogue_::
ld a, [wListScrollOffset]
ld [wSavedListScrollOffset], a
call UpdateSprites
xor a
ld [wBoughtOrSoldItemInMart], a
.loop
xor a
ld [wListScrollOffset], a
ld [wCurrentMenuItem], a
ld [wPlayerMonNumber], a
inc a
ld [wPrintItemPrices], a
ld a, MONEY_BOX
ld [wTextBoxID], a
call DisplayTextBoxID
ld a, BUY_SELL_QUIT_MENU
ld [wTextBoxID], a
call DisplayTextBoxID
; This code is useless. It copies the address of the pokemart's inventory to hl,
; but the address is never used.
ld hl, wItemListPointer
ld a, [hli]
ld l, [hl]
ld h, a
ld a, [wMenuExitMethod]
cp CANCELLED_MENU
jp z, .done
ld a, [wChosenMenuItem]
and a ; buying?
jp z, .buyMenu
dec a ; selling?
jp z, .sellMenu
dec a ; quitting?
jp z, .done
.sellMenu
; the same variables are set again below, so this code has no effect
xor a
ld [wPrintItemPrices], a
ld a, INIT_BAG_ITEM_LIST
ld [wInitListType], a
callab InitList
ld a, [wNumBagItems]
and a
jp z, .bagEmpty
ld hl, PokemonSellingGreetingText
call PrintText
call SaveScreenTilesToBuffer1 ; save screen
.sellMenuLoop
call LoadScreenTilesFromBuffer1 ; restore saved screen
ld a, MONEY_BOX
ld [wTextBoxID], a
call DisplayTextBoxID ; draw money text box
ld hl, wNumBagItems
ld a, l
ld [wListPointer], a
ld a, h
ld [wListPointer + 1], a
xor a
ld [wPrintItemPrices], a
ld [wCurrentMenuItem], a
ld a, ITEMLISTMENU
ld [wListMenuID], a
call DisplayListMenuID
jp c, .returnToMainPokemartMenu ; if the player closed the menu
.confirmItemSale ; if the player is trying to sell a specific item
call IsKeyItem
ld a, [wIsKeyItem]
and a
jr nz, .unsellableItem
ld a, [wcf91]
call IsItemHM
jr c, .unsellableItem
ld a, PRICEDITEMLISTMENU
ld [wListMenuID], a
ld [hHalveItemPrices], a ; halve prices when selling
call DisplayChooseQuantityMenu
inc a
jr z, .sellMenuLoop ; if the player closed the choose quantity menu with the B button
ld hl, PokemartTellSellPriceText
lb bc, 14, 1 ; location that PrintText always prints to, this is useless
call PrintText
coord hl, 14, 7
lb bc, 8, 15
ld a, TWO_OPTION_MENU
ld [wTextBoxID], a
call DisplayTextBoxID ; yes/no menu
ld a, [wMenuExitMethod]
cp CHOSE_SECOND_ITEM
jr z, .sellMenuLoop ; if the player chose No or pressed the B button
; The following code is supposed to check if the player chose No, but the above
; check already catches it.
ld a, [wChosenMenuItem]
dec a
jr z, .sellMenuLoop
.sellItem
ld a, [wBoughtOrSoldItemInMart]
and a
jr nz, .skipSettingFlag1
inc a
ld [wBoughtOrSoldItemInMart], a
.skipSettingFlag1
call AddAmountSoldToMoney
ld hl, wNumBagItems
call RemoveItemFromInventory
jp .sellMenuLoop
.unsellableItem
ld hl, PokemartUnsellableItemText
call PrintText
jp .returnToMainPokemartMenu
.bagEmpty
ld hl, PokemartItemBagEmptyText
call PrintText
call SaveScreenTilesToBuffer1
jp .returnToMainPokemartMenu
.buyMenu
; the same variables are set again below, so this code has no effect
ld a, 1
ld [wPrintItemPrices], a
ld a, INIT_OTHER_ITEM_LIST
ld [wInitListType], a
callab InitList
ld hl, PokemartBuyingGreetingText
call PrintText
call SaveScreenTilesToBuffer1
.buyMenuLoop
call LoadScreenTilesFromBuffer1
ld a, MONEY_BOX
ld [wTextBoxID], a
call DisplayTextBoxID
ld hl, wItemList
ld a, l
ld [wListPointer], a
ld a, h
ld [wListPointer + 1], a
xor a
ld [wCurrentMenuItem], a
inc a
ld [wPrintItemPrices], a
inc a ; a = 2 (PRICEDITEMLISTMENU)
ld [wListMenuID], a
call DisplayListMenuID
jr c, .returnToMainPokemartMenu ; if the player closed the menu
ld a, 99
ld [wMaxItemQuantity], a
xor a
ld [hHalveItemPrices], a ; don't halve item prices when buying
call DisplayChooseQuantityMenu
inc a
jr z, .buyMenuLoop ; if the player closed the choose quantity menu with the B button
ld a, [wcf91] ; item ID
ld [wd11e], a ; store item ID for GetItemName
call GetItemName
call CopyStringToCF4B ; copy name to wcf4b
ld hl, PokemartTellBuyPriceText
call PrintText
coord hl, 14, 7
lb bc, 8, 15
ld a, TWO_OPTION_MENU
ld [wTextBoxID], a
call DisplayTextBoxID ; yes/no menu
ld a, [wMenuExitMethod]
cp CHOSE_SECOND_ITEM
jp z, .buyMenuLoop ; if the player chose No or pressed the B button
; The following code is supposed to check if the player chose No, but the above
; check already catches it.
ld a, [wChosenMenuItem]
dec a
jr z, .buyMenuLoop
.buyItem
call .isThereEnoughMoney
jr c, .notEnoughMoney
ld hl, wNumBagItems
call AddItemToInventory
jr nc, .bagFull
call SubtractAmountPaidFromMoney
ld a, [wBoughtOrSoldItemInMart]
and a
jr nz, .skipSettingFlag2
ld a, 1
ld [wBoughtOrSoldItemInMart], a
.skipSettingFlag2
ld a, SFX_PURCHASE
call PlaySoundWaitForCurrent
call WaitForSoundToFinish
ld hl, PokemartBoughtItemText
call PrintText
jp .buyMenuLoop
.returnToMainPokemartMenu
call LoadScreenTilesFromBuffer1
ld a, MONEY_BOX
ld [wTextBoxID], a
call DisplayTextBoxID
ld hl, PokemartAnythingElseText
call PrintText
jp .loop
.isThereEnoughMoney
ld de, wPlayerMoney
ld hl, hMoney
ld c, 3 ; length of money in bytes
jp StringCmp
.notEnoughMoney
ld hl, PokemartNotEnoughMoneyText
call PrintText
jr .returnToMainPokemartMenu
.bagFull
ld hl, PokemartItemBagFullText
call PrintText
jr .returnToMainPokemartMenu
.done
ld hl, PokemartThankYouText
call PrintText
ld a, 1
ld [wUpdateSpritesEnabled], a
call UpdateSprites
ld a, [wSavedListScrollOffset]
ld [wListScrollOffset], a
ret
PokemartBuyingGreetingText:
TX_FAR _PokemartBuyingGreetingText
db "@"
PokemartTellBuyPriceText:
TX_FAR _PokemartTellBuyPriceText
db "@"
PokemartBoughtItemText:
TX_FAR _PokemartBoughtItemText
db "@"
PokemartNotEnoughMoneyText:
TX_FAR _PokemartNotEnoughMoneyText
db "@"
PokemartItemBagFullText:
TX_FAR _PokemartItemBagFullText
db "@"
PokemonSellingGreetingText:
TX_FAR _PokemonSellingGreetingText
db "@"
PokemartTellSellPriceText:
TX_FAR _PokemartTellSellPriceText
db "@"
PokemartItemBagEmptyText:
TX_FAR _PokemartItemBagEmptyText
db "@"
PokemartUnsellableItemText:
TX_FAR _PokemartUnsellableItemText
db "@"
PokemartThankYouText:
TX_FAR _PokemartThankYouText
db "@"
PokemartAnythingElseText:
TX_FAR _PokemartAnythingElseText
db "@"

View file

@ -1,15 +0,0 @@
RemoveGuardDrink::
ld hl, GuardDrinksList
.drinkLoop
ld a, [hli]
ld [$ffdb], a
and a
ret z
push hl
ld b, a
call IsItemInBag
pop hl
jr z, .drinkLoop
jpba RemoveItemByID
INCLUDE "data/guard_drink_items.asm"

View file

@ -1,25 +0,0 @@
SetLastBlackoutMap:
; Set the map to return to when
; blacking out or using Teleport or Dig.
; Safari rest houses don't count.
push hl
ld hl, SafariZoneRestHouses
ld a, [wCurMap]
ld b, a
.loop
ld a, [hli]
cp -1
jr z, .notresthouse
cp b
jr nz, .loop
jr .done
.notresthouse
ld a, [wLastMap]
ld [wLastBlackoutMap], a
.done
pop hl
ret
INCLUDE "data/rest_house_maps.asm"

View file

@ -0,0 +1,149 @@
SpecialWarpIn::
call LoadSpecialWarpData
predef LoadTilesetHeader
ld hl, wd732
bit 2, [hl] ; dungeon warp or fly warp?
res 2, [hl]
jr z, .next
; if dungeon warp or fly warp
ld a, [wDestinationMap]
jr .next2
.next
bit 1, [hl]
jr z, .next3
call EmptyFunc
.next3
ld a, 0
.next2
ld b, a
ld a, [wd72d]
and a
jr nz, .next4
ld a, b
.next4
ld hl, wd732
bit 4, [hl] ; dungeon warp?
ret nz
; if not dungeon warp
ld [wLastMap], a
ret
; gets the map ID, tile block map view pointer, tileset, and coordinates
LoadSpecialWarpData:
ld a, [wd72d]
cp TRADE_CENTER
jr nz, .notTradeCenter
ld hl, TradeCenterSpec1
ld a, [hSerialConnectionStatus]
cp USING_INTERNAL_CLOCK ; which gameboy is clocking determines who is on the left and who is on the right
jr z, .copyWarpData
ld hl, TradeCenterSpec2
jr .copyWarpData
.notTradeCenter
cp COLOSSEUM
jr nz, .notColosseum
ld hl, ColosseumSpec1
ld a, [hSerialConnectionStatus]
cp USING_INTERNAL_CLOCK
jr z, .copyWarpData
ld hl, ColosseumSpec2
jr .copyWarpData
.notColosseum
ld a, [wd732]
bit 1, a
jr nz, .notFirstMap
bit 2, a
jr nz, .notFirstMap
ld hl, FirstMapSpec
.copyWarpData
ld de, wCurMap
ld c, $7
.copyWarpDataLoop
ld a, [hli]
ld [de], a
inc de
dec c
jr nz, .copyWarpDataLoop
ld a, [hli]
ld [wCurMapTileset], a
xor a
jr .done
.notFirstMap
ld a, [wLastMap] ; this value is overwritten before it's ever read
ld hl, wd732
bit 4, [hl] ; used dungeon warp (jumped down hole/waterfall)?
jr nz, .usedDunegonWarp
bit 6, [hl] ; return to last pokemon center (or player's house)?
res 6, [hl]
jr z, .otherDestination
; return to last pokemon center or player's house
ld a, [wLastBlackoutMap]
jr .usedFlyWarp
.usedDunegonWarp
ld hl, wd72d
res 4, [hl]
ld a, [wDungeonWarpDestinationMap]
ld b, a
ld [wCurMap], a
ld a, [wWhichDungeonWarp]
ld c, a
ld hl, DungeonWarpList
ld de, 0
ld a, 6
ld [wDungeonWarpDataEntrySize], a
.dungeonWarpListLoop
ld a, [hli]
cp b
jr z, .matchedDungeonWarpDestinationMap
inc hl
jr .nextDungeonWarp
.matchedDungeonWarpDestinationMap
ld a, [hli]
cp c
jr z, .matchedDungeonWarpID
.nextDungeonWarp
ld a, [wDungeonWarpDataEntrySize]
add e
ld e, a
jr .dungeonWarpListLoop
.matchedDungeonWarpID
ld hl, DungeonWarpData
add hl, de
jr .copyWarpData2
.otherDestination
ld a, [wDestinationMap]
.usedFlyWarp
ld b, a
ld [wCurMap], a
ld hl, FlyWarpDataPtr
.flyWarpDataPtrLoop
ld a, [hli]
inc hl
cp b
jr z, .foundFlyWarpMatch
inc hl
inc hl
jr .flyWarpDataPtrLoop
.foundFlyWarpMatch
ld a, [hli]
ld h, [hl]
ld l, a
.copyWarpData2
ld de, wCurrentTileBlockMapViewPointer
ld c, $6
.copyWarpDataLoop2
ld a, [hli]
ld [de], a
inc de
dec c
jr nz, .copyWarpDataLoop2
xor a ; OVERWORLD
ld [wCurMapTileset], a
.done
ld [wYOffsetSinceLastSpecialWarp], a
ld [wXOffsetSinceLastSpecialWarp], a
ld a, $ff ; the player's coordinates have already been updated using a special warp, so don't use any of the normal warps
ld [wDestinationWarpID], a
ret
INCLUDE "data/special_warps.asm"

View file

@ -0,0 +1,25 @@
UpdateSpriteFacingOffsetAndDelayMovement::
ld h, $c2
ld a, [H_CURRENTSPRITEOFFSET]
add $8
ld l, a
ld a, $7f ; maximum movement delay
ld [hl], a ; c2x8 (movement delay)
dec h
ld a, [H_CURRENTSPRITEOFFSET]
add $9
ld l, a
ld a, [hld] ; c1x9 (facing direction)
ld b, a
xor a
ld [hld], a
ld [hl], a ; c1x8 (walk animation frame)
ld a, [H_CURRENTSPRITEOFFSET]
add $2
ld l, a
ld a, [hl] ; c1x2 (facing and animation table offset)
or b ; or in the facing direction
ld [hld], a
ld a, $2 ; delayed movement status
ld [hl], a ; c1x1 (movement status)
ret