summaryrefslogtreecommitdiff
path: root/home/overworld.asm
diff options
context:
space:
mode:
Diffstat (limited to 'home/overworld.asm')
-rw-r--r--home/overworld.asm2917
1 files changed, 1419 insertions, 1498 deletions
diff --git a/home/overworld.asm b/home/overworld.asm
index fad9f29d..0b2f527f 100644
--- a/home/overworld.asm
+++ b/home/overworld.asm
@@ -1,14 +1,9 @@
-HandleMidJump::
-; Handle the player jumping down
-; a ledge in the overworld.
- jpba _HandleMidJump
-
EnterMap::
; Load a new map.
ld a, $ff
ld [wJoyIgnore], a
call LoadMapData
- callba ClearVariablesAfterLoadingMapData
+ callba ClearVariablesAfterLoadingMapData ; 3:407c
ld hl, wd72c
bit 0, [hl] ; has the player already made 3 steps since the last battle?
jr z, .skipGivingThreeStepsOfNoRandomBattles
@@ -24,11 +19,18 @@ EnterMap::
ld a, [hl]
and 1 << 4 | 1 << 3 ; fly warp or dungeon warp
jr z, .didNotEnterUsingFlyWarpOrDungeonWarp
- res 3, [hl]
callba EnterMapAnim
call UpdateSprites
+ ld hl, wd732
+ res 3, [hl]
+ ld hl, wd72e
+ res 4, [hl]
.didNotEnterUsingFlyWarpOrDungeonWarp
+ call IsSurfingPikachuInParty
callba CheckForceBikeOrSurf ; handle currents in SF islands and forced bike riding in cycling road
+ ld hl, wd732
+ bit 4, [hl]
+ res 4, [hl]
ld hl, wd72d
res 5, [hl]
call UpdateSprites
@@ -42,645 +44,652 @@ OverworldLoop::
call DelayFrame
OverworldLoopLessDelay::
call DelayFrame
+ call IsSurfingPikachuInParty
call LoadGBPal
- ld a,[wd736]
- bit 6,a ; jumping down a ledge?
- call nz, HandleMidJump
- ld a,[wWalkCounter]
+ call HandleMidJump
+ ld a, [wWalkCounter]
and a
- jp nz,.moveAhead ; if the player sprite has not yet completed the walking animation
+ jp nz, .moveAhead ; if the player sprite has not yet completed the walking animation
call JoypadOverworld ; get joypad state (which is possibly simulated)
- callba SafariZoneCheck
- ld a,[wSafariZoneGameOver]
+ callba SafariZoneCheck ; 7:6321
+ ld a, [wSafariZoneGameOver]
and a
- jp nz,WarpFound2
- ld hl,wd72d
- bit 3,[hl]
- res 3,[hl]
- jp nz,WarpFound2
- ld a,[wd732]
- and a,1 << 4 | 1 << 3 ; fly warp or dungeon warp
- jp nz,HandleFlyWarpOrDungeonWarp
- ld a,[wCurOpponent]
+ jp nz, WarpFound2
+ ld hl, wd72d
+ bit 3, [hl]
+ res 3, [hl]
+ jp nz, WarpFound2
+ ld a, [wd732]
+ and 1 << 4 | 1 << 3 ; fly warp or dungeon warp
+ jp nz, HandleFlyWarpOrDungeonWarp
+ ld a, [wCurOpponent]
and a
- jp nz,.newBattle
- ld a,[wd730]
- bit 7,a ; are we simulating button presses?
- jr z,.notSimulating
- ld a,[hJoyHeld]
+ jp nz, .newBattle
+ ld a, [wd730]
+ bit 7, a ; are we simulating button presses?
+ jr z, .notSimulating
+ ld a, [hJoyHeld]
jr .checkIfStartIsPressed
+
.notSimulating
- ld a,[hJoyPressed]
+ ld a, [hJoyPressed]
.checkIfStartIsPressed
- bit 3,a ; start button
- jr z,.startButtonNotPressed
+ bit 3, a ; start button
+ jr z, .startButtonNotPressed
; if START is pressed
xor a
- ld [hSpriteIndexOrTextID],a ; start menu text ID
+ ld [hSpriteIndexOrTextID], a ; start menu text ID
jp .displayDialogue
+
.startButtonNotPressed
- bit 0,a ; A button
- jp z,.checkIfDownButtonIsPressed
+ bit 0, a ; A button
+ jp z, .checkIfDownButtonIsPressed
; if A is pressed
- ld a,[wd730]
- bit 2,a
- jp nz,.noDirectionButtonsPressed
+ ld a, [wd730]
+ bit 2, a
+ jp nz, .noDirectionButtonsPressed
call IsPlayerCharacterBeingControlledByGame
- jr nz,.checkForOpponent
+ jr nz, .checkForOpponent
call CheckForHiddenObjectOrBookshelfOrCardKeyDoor
- ld a,[$ffeb]
+ ld a, [$ffeb]
and a
- jp z,OverworldLoop ; jump if a hidden object or bookshelf was found, but not if a card key door was found
+ jp z, OverworldLoop ; jump if a hidden object or bookshelf was found, but not if a card key door was found
+ xor a
+ ld [wd436], a ; new yellow address
call IsSpriteOrSignInFrontOfPlayer
- ld a,[hSpriteIndexOrTextID]
+ call Func_0ffe
+ ld a, [hSpriteIndexOrTextID]
and a
- jp z,OverworldLoop
+ jp z, OverworldLoop
.displayDialogue
predef GetTileAndCoordsInFrontOfPlayer
call UpdateSprites
- ld a,[wFlags_0xcd60]
- bit 2,a
- jr nz,.checkForOpponent
- bit 0,a
- jr nz,.checkForOpponent
+ ld a, [wFlags_0xcd60]
+ bit 2, a
+ jr nz, .checkForOpponent
+ bit 0, a
+ jr nz, .checkForOpponent
aCoord 8, 9
- ld [wTilePlayerStandingOn],a ; unused?
+ ld [wTilePlayerStandingOn], a ; unused?
call DisplayTextID ; display either the start menu or the NPC/sign text
- ld a,[wEnteringCableClub]
+ ld a, [wEnteringCableClub]
and a
- jr z,.checkForOpponent
- dec a
- ld a,0
- ld [wEnteringCableClub],a
- jr z,.changeMap
-; XXX can this code be reached?
- predef LoadSAV
- ld a,[wCurMap]
- ld [wDestinationMap],a
- call SpecialWarpIn
- ld a,[wCurMap]
- call SwitchToMapRomBank ; switch to the ROM bank of the current map
- ld hl,wCurMapTileset
- set 7,[hl]
-.changeMap
+ jr z, .checkForOpponent
+ xor a
+ ld [wLinkTimeoutCounter], a
jp EnterMap
+
+; predef LoadSAV
+; ld a, [wCurMap]
+; ld [wDestinationMap], a
+; call SpecialWarpIn
+; ld a, [wCurMap]
+; call SwitchToMapRomBank ; switch to the ROM bank of the current map
+; ld hl, wCurMapTileset
+; set 7, [hl]
.checkForOpponent
- ld a,[wCurOpponent]
+ ld a, [wCurOpponent]
and a
- jp nz,.newBattle
+ jp nz, .newBattle
jp OverworldLoop
+
.noDirectionButtonsPressed
- ld hl,wFlags_0xcd60
- res 2,[hl]
- call UpdateSprites
- ld a,1
- ld [wCheckFor180DegreeTurn],a
- ld a,[wPlayerMovingDirection] ; the direction that was pressed last time
+ call UpdateSprites ; 231c
+ ld hl, wFlags_0xcd60
+ res 2, [hl]
+ xor a
+ ld [wd435], a
+ ld a, $1
+ ld [wCheckFor180DegreeTurn], a
+ ld a, [wPlayerMovingDirection] ; the direction that was pressed last time
and a
- jp z,OverworldLoop
+ jr z, .overworldloop
; if a direction was pressed last time
- ld [wPlayerLastStopDirection],a ; save the last direction
+ ld [wPlayerLastStopDirection], a ; save the last direction
xor a
- ld [wPlayerMovingDirection],a ; zero the direction
+ ld [wPlayerMovingDirection], a ; zero the direction
+.overworldloop
jp OverworldLoop
+
.checkIfDownButtonIsPressed
- ld a,[hJoyHeld] ; current joypad state
- bit 7,a ; down button
- jr z,.checkIfUpButtonIsPressed
- ld a,1
- ld [wSpriteStateData1 + 3],a ; delta Y
- ld a,PLAYER_DIR_DOWN
+ ld a, [hJoyHeld] ; current joypad state
+ bit 7, a ; down button
+ jr z, .checkIfUpButtonIsPressed
+ ld a, 1
+ ld [wSpriteStateData1 + 3], a ; delta Y
+ ld a, PLAYER_DIR_DOWN
jr .handleDirectionButtonPress
+
.checkIfUpButtonIsPressed
- bit 6,a ; up button
- jr z,.checkIfLeftButtonIsPressed
- ld a,-1
- ld [wSpriteStateData1 + 3],a ; delta Y
- ld a,PLAYER_DIR_UP
+ bit 6, a ; up button
+ jr z, .checkIfLeftButtonIsPressed
+ ld a, -1
+ ld [wSpriteStateData1 + 3], a ; delta Y
+ ld a, PLAYER_DIR_UP
jr .handleDirectionButtonPress
+
.checkIfLeftButtonIsPressed
- bit 5,a ; left button
- jr z,.checkIfRightButtonIsPressed
- ld a,-1
- ld [wSpriteStateData1 + 5],a ; delta X
- ld a,PLAYER_DIR_LEFT
+ bit 5, a ; left button
+ jr z, .checkIfRightButtonIsPressed
+ ld a, -1
+ ld [wSpriteStateData1 + 5], a ; delta X
+ ld a, PLAYER_DIR_LEFT
jr .handleDirectionButtonPress
+
.checkIfRightButtonIsPressed
- bit 4,a ; right button
- jr z,.noDirectionButtonsPressed
- ld a,1 ; PLAYER_DIR_RIGHT
- ld [wSpriteStateData1 + 5],a ; delta X
+ bit 4, a ; right button
+ jr z, .noDirectionButtonsPressed
+ ld a, $1
+ ld [wSpriteStateData1 + 5], a
+ ld a, $1
.handleDirectionButtonPress
- ld [wPlayerDirection],a ; new direction
- ld a,[wd730]
- bit 7,a ; are we simulating button presses?
- jr nz,.noDirectionChange ; ignore direction changes if we are
- ld a,[wCheckFor180DegreeTurn]
+ ld [wPlayerDirection], a ; new direction
+ ld a, [wd730]
+ bit 7, a ; are we simulating button presses?
+ jr nz, .noDirectionChange ; ignore direction changes if we are
+ ld a, [wCheckFor180DegreeTurn]
and a
- jr z,.noDirectionChange
- ld a,[wPlayerDirection] ; new direction
- ld b,a
- ld a,[wPlayerLastStopDirection] ; old direction
+ jr z, .noDirectionChange
+ ld a, [wPlayerDirection] ; new direction
+ ld b, a
+ ld a, [wPlayerLastStopDirection] ; old direction
cp b
- jr z,.noDirectionChange
-; Check whether the player did a 180-degree turn.
-; It appears that this code was supposed to show the player rotate by having
-; the player's sprite face an intermediate direction before facing the opposite
-; direction (instead of doing an instantaneous about-face), but the intermediate
-; direction is only set for a short period of time. It is unlikely for it to
-; ever be visible because DelayFrame is called at the start of OverworldLoop and
-; normally not enough cycles would be executed between then and the time the
-; direction is set for V-blank to occur while the direction is still set.
- swap a ; put old direction in upper half
- or b ; put new direction in lower half
- cp a,(PLAYER_DIR_DOWN << 4) | PLAYER_DIR_UP ; change dir from down to up
- jr nz,.notDownToUp
- ld a,PLAYER_DIR_LEFT
- ld [wPlayerMovingDirection],a
- jr .holdIntermediateDirectionLoop
-.notDownToUp
- cp a,(PLAYER_DIR_UP << 4) | PLAYER_DIR_DOWN ; change dir from up to down
- jr nz,.notUpToDown
- ld a,PLAYER_DIR_RIGHT
- ld [wPlayerMovingDirection],a
- jr .holdIntermediateDirectionLoop
-.notUpToDown
- cp a,(PLAYER_DIR_RIGHT << 4) | PLAYER_DIR_LEFT ; change dir from right to left
- jr nz,.notRightToLeft
- ld a,PLAYER_DIR_DOWN
- ld [wPlayerMovingDirection],a
- jr .holdIntermediateDirectionLoop
-.notRightToLeft
- cp a,(PLAYER_DIR_LEFT << 4) | PLAYER_DIR_RIGHT ; change dir from left to right
- jr nz,.holdIntermediateDirectionLoop
- ld a,PLAYER_DIR_UP
- ld [wPlayerMovingDirection],a
-.holdIntermediateDirectionLoop
- ld hl,wFlags_0xcd60
- set 2,[hl]
- ld hl,wCheckFor180DegreeTurn
- dec [hl]
- jr nz,.holdIntermediateDirectionLoop
- ld a,[wPlayerDirection]
- ld [wPlayerMovingDirection],a
+ jr z, .noDirectionChange
+ ld a, $8
+ ld [wd435], a
+; unlike in red/blue, yellow does not have the 180 degrees odd code
+ ld hl, wFlags_0xcd60
+ set 2, [hl]
+ xor a
+ ld [wCheckFor180DegreeTurn], a
+ ld a, [wPlayerDirection]
+ ld [wPlayerMovingDirection], a
call NewBattle
- jp c,.battleOccurred
+ jp c, .battleOccurred
jp OverworldLoop
+
.noDirectionChange
- ld a,[wPlayerDirection] ; current direction
- ld [wPlayerMovingDirection],a ; save direction
+ ld a, [wPlayerDirection] ; current direction
+ ld [wPlayerMovingDirection], a ; save direction
call UpdateSprites
- ld a,[wWalkBikeSurfState]
- cp a,$02 ; surfing
- jr z,.surfing
+ ld a, [wWalkBikeSurfState]
+ cp $02 ; surfing
+ jr z, .surfing
; not surfing
call CollisionCheckOnLand
- jr nc,.noCollision
+ jr nc, .noCollision
; collision occurred
push hl
- ld hl,wd736
- bit 2,[hl] ; standing on warp flag
+ ld hl, wd736
+ bit 2, [hl] ; standing on warp flag
pop hl
- jp z,OverworldLoop
+ jp z, OverworldLoop
; collision occurred while standing on a warp
push hl
call ExtraWarpCheck ; sets carry if there is a potential to warp
pop hl
- jp c,CheckWarpsCollision
+ jp c, CheckWarpsCollision
jp OverworldLoop
+
.surfing
call CollisionCheckOnWater
- jp c,OverworldLoop
+ jp c, OverworldLoop
.noCollision
- ld a,$08
- ld [wWalkCounter],a
+ ld a, $08
+ ld [wWalkCounter], a
+ callab Func_fcc08
jr .moveAhead2
+
.moveAhead
- ld a,[wd736]
- bit 7,a
- jr z,.noSpinning
- callba LoadSpinnerArrowTiles ; spin while moving
-.noSpinning
- call UpdateSprites
+ call IsSpinning
+ call UpdateSprites ; move sprites
.moveAhead2
- ld hl,wFlags_0xcd60
- res 2,[hl]
- ld a,[wWalkBikeSurfState]
- dec a ; riding a bike?
- jr nz,.normalPlayerSpriteAdvancement
- ld a,[wd736]
- bit 6,a ; jumping a ledge?
- jr nz,.normalPlayerSpriteAdvancement
- call BikeSpeedup ; if riding a bike and not jumping a ledge
-.normalPlayerSpriteAdvancement
+ ld hl, wFlags_0xcd60
+ res 2, [hl]
+ xor a
+ ld [wd435], a
+ call DoBikeSpeedup
call AdvancePlayerSprite
- ld a,[wWalkCounter]
+ ld a, [wWalkCounter]
and a
- jp nz,CheckMapConnections ; it seems like this check will never succeed (the other place where CheckMapConnections is run works)
+ jp nz, CheckMapConnections ; it seems like this check will never succeed (the other place where CheckMapConnections is run works)
; walking animation finished
- ld a,[wd730]
- bit 7,a
- jr nz,.doneStepCounting ; if button presses are being simulated, don't count steps
-; step counting
- ld hl,wStepCounter
- dec [hl]
- ld a,[wd72c]
- bit 0,a
- jr z,.doneStepCounting
- ld hl,wNumberOfNoRandomBattleStepsLeft
- dec [hl]
- jr nz,.doneStepCounting
- ld hl,wd72c
- res 0,[hl] ; indicate that the player has stepped thrice since the last battle
-.doneStepCounting
- CheckEvent EVENT_IN_SAFARI_ZONE
- jr z,.notSafariZone
+ call StepCountCheck
+ CheckEvent EVENT_IN_SAFARI_ZONE ; in the safari zone?
+ jr z, .notSafariZone
callba SafariZoneCheckSteps
- ld a,[wSafariZoneGameOver]
+ ld a, [wSafariZoneGameOver]
and a
- jp nz,WarpFound2
+ jp nz, WarpFound2
.notSafariZone
- ld a,[wIsInBattle]
+ ld a, [wIsInBattle]
and a
- jp nz,CheckWarpsNoCollision
+ jp nz, CheckWarpsNoCollision
predef ApplyOutOfBattlePoisonDamage ; also increment daycare mon exp
- ld a,[wOutOfBattleBlackout]
+ ld a, [wOutOfBattleBlackout]
and a
- jp nz,HandleBlackOut ; if all pokemon fainted
+ jp nz, HandleBlackOut ; if all pokemon fainted
.newBattle
call NewBattle
- ld hl,wd736
- res 2,[hl] ; standing on warp flag
- jp nc,CheckWarpsNoCollision ; check for warps if there was no battle
+ ld hl, wd736
+ res 2, [hl] ; standing on warp flag
+ jp nc, CheckWarpsNoCollision ; check for warps if there was no battle
.battleOccurred
- ld hl,wd72d
- res 6,[hl]
- ld hl,wFlags_D733
- res 3,[hl]
- ld hl,wCurrentMapScriptFlags
- set 5,[hl]
- set 6,[hl]
+ ld hl, wd72d
+ res 6, [hl]
+ ld hl, wFlags_D733
+ res 3, [hl]
+ ld hl, wCurrentMapScriptFlags
+ set 5, [hl]
+ set 6, [hl]
xor a
- ld [hJoyHeld],a
- ld a,[wCurMap]
- cp a,CINNABAR_GYM
- jr nz,.notCinnabarGym
+ ld [hJoyHeld], a
+ ld a, [wCurMap]
+ cp CINNABAR_GYM
+ jr nz, .notCinnabarGym
SetEvent EVENT_2A7
.notCinnabarGym
- ld hl,wd72e
- set 5,[hl]
- ld a,[wCurMap]
- cp a,OAKS_LAB
- jp z,.noFaintCheck ; no blacking out if the player lost to the rival in Oak's lab
+ ld hl, wd72e
+ set 5, [hl]
+ ld a, [wCurMap]
+ cp OAKS_LAB
+ jp z, .noFaintCheck ; no blacking out if the player lost to the rival in Oak's lab
callab AnyPartyAlive
- ld a,d
+ ld a, d
and a
- jr z,.allPokemonFainted
+ jr z, AllPokemonFainted
.noFaintCheck
- ld c,10
+ ld c, 10
call DelayFrames
jp EnterMap
-.allPokemonFainted
- ld a,$ff
- ld [wIsInBattle],a
+
+StepCountCheck::
+ ld a, [wd730]
+ bit 7, a
+ jr nz, .doneStepCounting ; if button presses are being simulated, don't count steps
+; step counting
+ ld hl, wStepCounter
+ dec [hl]
+ ld a, [wd72c]
+ bit 0, a
+ jr z, .doneStepCounting
+ ld hl, wNumberOfNoRandomBattleStepsLeft
+ dec [hl]
+ jr nz, .doneStepCounting
+ ld hl, wd72c
+ res 0, [hl] ; indicate that the player has stepped thrice since the last battle
+.doneStepCounting
+ ret
+
+AllPokemonFainted::
+ ld a, $ff
+ ld [wIsInBattle], a
call RunMapScript
jp HandleBlackOut
; function to determine if there will be a battle and execute it (either a trainer battle or wild battle)
; sets carry if a battle occurred and unsets carry if not
NewBattle::
- ld a,[wd72d]
- bit 4,a
- jr nz,.noBattle
+ ld a, [wd72d]
+ bit 4, a
+ jr nz, .noBattle
call IsPlayerCharacterBeingControlledByGame
- jr nz,.noBattle ; no battle if the player character is under the game's control
- ld a,[wd72e]
- bit 4,a
- jr nz,.noBattle
- jpba InitBattle
+ jr nz, .noBattle ; no battle if the player character is under the game's control
+ ld a, [wd72e]
+ bit 4, a
+ jr nz, .noBattle
+ jpba InitBattle ; 3d:5ff2
.noBattle
and a
ret
-; function to make bikes twice as fast as walking
-BikeSpeedup::
- ld a,[wNPCMovementScriptPointerTableNum]
+DoBikeSpeedup::
+ ld a, [wWalkBikeSurfState]
+ dec a ; riding a bike?
+ ret nz
+ ld a, [wd736]
+ bit 6, a
+ ret nz
+ ld a, [wNPCMovementScriptPointerTableNum]
and a
ret nz
- ld a,[wCurMap]
- cp a,ROUTE_17 ; Cycling Road
- jr nz,.goFaster
- ld a,[hJoyHeld]
- and a,D_UP | D_LEFT | D_RIGHT
+ ld a, [wCurMap]
+ cp ROUTE_17 ; cycling road
+ jr nz, .goFaster
+ ld a, [hJoyHeld]
+ and D_UP | D_LEFT | D_RIGHT
ret nz
.goFaster
- jp AdvancePlayerSprite
+ call AdvancePlayerSprite
+ ret
; check if the player has stepped onto a warp after having not collided
CheckWarpsNoCollision::
- ld a,[wNumberOfWarps]
+ ld a, [wNumberOfWarps]
and a
- jp z,CheckMapConnections
- ld a,[wNumberOfWarps]
- ld b,0
- ld c,a
- ld a,[wYCoord]
- ld d,a
- ld a,[wXCoord]
- ld e,a
- ld hl,wWarpEntries
+ jp z, CheckMapConnections
+ ld b, 0
+ ld a, [wNumberOfWarps]
+ ld c, a
+ ld a, [wYCoord]
+ ld d, a
+ ld a, [wXCoord]
+ ld e, a
+ ld hl, wWarpEntries
CheckWarpsNoCollisionLoop::
- ld a,[hli] ; check if the warp's Y position matches
+ ld a, [hli] ; check if the warp's Y position matches
cp d
- jr nz,CheckWarpsNoCollisionRetry1
- ld a,[hli] ; check if the warp's X position matches
+ jr nz, CheckWarpsNoCollisionRetry1
+ ld a, [hli] ; check if the warp's X position matches
cp e
- jr nz,CheckWarpsNoCollisionRetry2
+ jr nz, CheckWarpsNoCollisionRetry2
; if a match was found
push hl
push bc
- ld hl,wd736
- set 2,[hl] ; standing on warp flag
+ ld hl, wd736
+ set 2, [hl] ; standing on warp flag
callba IsPlayerStandingOnDoorTileOrWarpTile
pop bc
pop hl
- jr c,WarpFound1 ; jump if standing on door or warp
+ jr c, WarpFound1 ; jump if standing on door or warp
push hl
push bc
call ExtraWarpCheck
pop bc
pop hl
- jr nc,CheckWarpsNoCollisionRetry2
+ jr nc, CheckWarpsNoCollisionRetry2
; if the extra check passed
- ld a,[wFlags_D733]
- bit 2,a
- jr nz,WarpFound1
+ ld a, [wFlags_D733]
+ bit 2, a
+ jr nz, WarpFound1
push de
push bc
call Joypad
pop bc
pop de
- ld a,[hJoyHeld]
- and a,D_DOWN | D_UP | D_LEFT | D_RIGHT
- jr z,CheckWarpsNoCollisionRetry2 ; if directional buttons aren't being pressed, do not pass through the warp
+ ld a, [hJoyHeld]
+ and D_DOWN | D_UP | D_LEFT | D_RIGHT
+ jr z, CheckWarpsNoCollisionRetry2 ; if directional buttons aren't being pressed, do not pass through the warp
jr WarpFound1
+CheckWarpsNoCollisionRetry1::
+ inc hl
+CheckWarpsNoCollisionRetry2::
+ inc hl
+ inc hl
+ContinueCheckWarpsNoCollisionLoop::
+ inc b ; increment warp number
+ dec c ; decrement number of warps
+ jp nz, CheckWarpsNoCollisionLoop
+ jp CheckMapConnections
+
; check if the player has stepped onto a warp after having collided
CheckWarpsCollision::
- ld a,[wNumberOfWarps]
- ld c,a
- ld hl,wWarpEntries
+ ld a, [wNumberOfWarps]
+ ld c, a
+ ld hl, wWarpEntries
.loop
- ld a,[hli] ; Y coordinate of warp
- ld b,a
- ld a,[wYCoord]
+ ld a, [hli] ; Y coordinate of warp
+ ld b, a
+ ld a, [wYCoord]
cp b
- jr nz,.retry1
- ld a,[hli] ; X coordinate of warp
- ld b,a
- ld a,[wXCoord]
+ jr nz, .retry1
+ ld a, [hli] ; X coordinate of warp
+ ld b, a
+ ld a, [wXCoord]
cp b
- jr nz,.retry2
- ld a,[hli]
- ld [wDestinationWarpID],a
- ld a,[hl]
- ld [hWarpDestinationMap],a
+ jr nz, .retry2
+ ld a, [hli]
+ ld [wDestinationWarpID], a
+ ld a, [hl]
+ ld [hWarpDestinationMap], a
jr WarpFound2
+
.retry1
inc hl
.retry2
inc hl
inc hl
dec c
- jr nz,.loop
+ jr nz, .loop
jp OverworldLoop
-CheckWarpsNoCollisionRetry1::
- inc hl
-CheckWarpsNoCollisionRetry2::
- inc hl
- inc hl
- jp ContinueCheckWarpsNoCollisionLoop
-
WarpFound1::
- ld a,[hli]
- ld [wDestinationWarpID],a
- ld a,[hli]
- ld [hWarpDestinationMap],a
+ ld a, [hli]
+ ld [wDestinationWarpID], a
+ ld a, [hli]
+ ld [hWarpDestinationMap], a
WarpFound2::
- ld a,[wNumberOfWarps]
+ ld a, [wNumberOfWarps]
sub c
- ld [wWarpedFromWhichWarp],a ; save ID of used warp
- ld a,[wCurMap]
- ld [wWarpedFromWhichMap],a
+ ld [wWarpedFromWhichWarp], a ; save ID of used warp
+ ld a, [wCurMap]
+ ld [wWarpedFromWhichMap], a
call CheckIfInOutsideMap
- jr nz,.indoorMaps
+ jr nz, .indoorMaps
; this is for handling "outside" maps that can't have the 0xFF destination map
- ld a,[wCurMap]
- ld [wLastMap],a
- ld a,[wCurMapWidth]
- ld [wUnusedD366],a ; not read
- ld a,[hWarpDestinationMap]
- ld [wCurMap],a
- cp a,ROCK_TUNNEL_1
- jr nz,.notRockTunnel
- ld a,$06
- ld [wMapPalOffset],a
+ ld a, [wCurMap]
+ ld [wLastMap], a
+ ld a, [wCurMapWidth]
+ ld [wUnusedD366], a ; not read
+ ld a, [hWarpDestinationMap]
+ ld [wCurMap], a
+ cp ROCK_TUNNEL_1
+ jr nz, .notRockTunnel
+ ld a, $06
+ ld [wMapPalOffset], a
call GBFadeOutToBlack
.notRockTunnel
+ callab CalculatePikachuSpawnState1 ; 3f:45fa
call PlayMapChangeSound
jr .done
-; for maps that can have the 0xFF destination map, which means to return to the outside map; not all these maps are necessarily indoors, though
+
+; for maps that can have the 0xFF destination map, which means to return to the outside map
+; not all these maps are necessarily indoors, though
.indoorMaps
- ld a,[hWarpDestinationMap] ; destination map
- cp a,$ff
- jr z,.goBackOutside
+ ld a, [hWarpDestinationMap] ; destination map
+ cp $ff
+ jr z, .goBackOutside
; if not going back to the previous map
- ld [wCurMap],a
+ ld [wCurMap], a
callba IsPlayerStandingOnWarpPadOrHole
- ld a,[wStandingOnWarpPadOrHole]
+ ld a, [wStandingOnWarpPadOrHole]
dec a ; is the player on a warp pad?
- jr nz,.notWarpPad
+ jr nz, .notWarpPad
; if the player is on a warp pad
- ld hl,wd732
- set 3,[hl]
call LeaveMapAnim
+ ld hl, wd732
+ set 3, [hl]
jr .skipMapChangeSound
+
.notWarpPad
call PlayMapChangeSound
.skipMapChangeSound
- ld hl,wd736
- res 0,[hl]
- res 1,[hl]
+ ld hl, wd736
+ res 0, [hl]
+ res 1, [hl]
+ callab CalculatePikachuSpawnState2 ; 3f:465b
jr .done
+
.goBackOutside
- ld a,[wLastMap]
- ld [wCurMap],a
+ callab CalculatePikachuSpawnState3 ; 3f:469a
+ ld a, [wLastMap]
+ ld [wCurMap], a
call PlayMapChangeSound
xor a
- ld [wMapPalOffset],a
+ ld [wMapPalOffset], a
.done
- ld hl,wd736
- set 0,[hl] ; have the player's sprite step out from the door (if there is one)
+ ld hl, wd736
+ set 0, [hl] ; have the player's sprite step out from the door (if there is one)
call IgnoreInputForHalfSecond
jp EnterMap
-ContinueCheckWarpsNoCollisionLoop::
- inc b ; increment warp number
- dec c ; decrement number of warps
- jp nz,CheckWarpsNoCollisionLoop
-
; if no matching warp was found
CheckMapConnections::
.checkWestMap
- ld a,[wXCoord]
- cp a,$ff
- jr nz,.checkEastMap
- ld a,[wMapConn3Ptr]
- ld [wCurMap],a
- ld a,[wWestConnectedMapXAlignment] ; new X coordinate upon entering west map
- ld [wXCoord],a
- ld a,[wYCoord]
- ld c,a
- ld a,[wWestConnectedMapYAlignment] ; Y adjustment upon entering west map
+ ld a, [wXCoord]
+ cp $ff
+ jr nz, .checkEastMap
+ ld a, [wMapConn3Ptr]
+ ld [wCurMap], a
+ ld a, [wWestConnectedMapXAlignment] ; new X coordinate upon entering west map
+ ld [wXCoord], a
+ ld a, [wYCoord]
+ ld c, a
+ ld a, [wWestConnectedMapYAlignment] ; Y adjustment upon entering west map
add c
- ld c,a
- ld [wYCoord],a
- ld a,[wWestConnectedMapViewPointer] ; pointer to upper left corner of map without adjustment for Y position
- ld l,a
- ld a,[wWestConnectedMapViewPointer + 1]
- ld h,a
+ ld c, a
+ ld [wYCoord], a
+ ld a, [wWestConnectedMapViewPointer] ; pointer to upper left corner of map without adjustment for Y position
+ ld l, a
+ ld a, [wWestConnectedMapViewPointer + 1]
+ ld h, a
srl c
- jr z,.savePointer1
+ jr z, .savePointer1
.pointerAdjustmentLoop1
- ld a,[wWestConnectedMapWidth] ; width of connected map
- add a,MAP_BORDER * 2
- ld e,a
- ld d,0
- ld b,0
- add hl,de
+ ld a, [wWestConnectedMapWidth] ; width of connected map
+ add MAP_BORDER * 2
+ ld e, a
+ ld d, 0
+ ld b, 0
+ add hl, de
dec c
- jr nz,.pointerAdjustmentLoop1
+ jr nz, .pointerAdjustmentLoop1
.savePointer1
- ld a,l
- ld [wCurrentTileBlockMapViewPointer],a ; pointer to upper left corner of current tile block map section
- ld a,h
- ld [wCurrentTileBlockMapViewPointer + 1],a
+ ld a, l
+ ld [wCurrentTileBlockMapViewPointer], a ; pointer to upper left corner of current tile block map section
+ ld a, h
+ ld [wCurrentTileBlockMapViewPointer + 1], a
jp .loadNewMap
+
.checkEastMap
- ld b,a
- ld a,[wCurrentMapWidth2] ; map width
+ ld b, a
+ ld a, [wCurrentMapWidth2] ; map width
cp b
- jr nz,.checkNorthMap
- ld a,[wMapConn4Ptr]
- ld [wCurMap],a
- ld a,[wEastConnectedMapXAlignment] ; new X coordinate upon entering east map
- ld [wXCoord],a
- ld a,[wYCoord]
- ld c,a
- ld a,[wEastConnectedMapYAlignment] ; Y adjustment upon entering east map
+ jr nz, .checkNorthMap
+ ld a, [wMapConn4Ptr]
+ ld [wCurMap], a
+ ld a, [wEastConnectedMapXAlignment] ; new X coordinate upon entering east map
+ ld [wXCoord], a
+ ld a, [wYCoord]
+ ld c, a
+ ld a, [wEastConnectedMapYAlignment] ; Y adjustment upon entering east map
add c
- ld c,a
- ld [wYCoord],a
- ld a,[wEastConnectedMapViewPointer] ; pointer to upper left corner of map without adjustment for Y position
- ld l,a
- ld a,[wEastConnectedMapViewPointer + 1]
- ld h,a
+ ld c, a
+ ld [wYCoord], a
+ ld a, [wEastConnectedMapViewPointer] ; pointer to upper left corner of map without adjustment for Y position
+ ld l, a
+ ld a, [wEastConnectedMapViewPointer + 1]
+ ld h, a
srl c
- jr z,.savePointer2
+ jr z, .savePointer2
.pointerAdjustmentLoop2
- ld a,[wEastConnectedMapWidth]
- add a,MAP_BORDER * 2
- ld e,a
- ld d,0
- ld b,0
- add hl,de
+ ld a, [wEastConnectedMapWidth]
+ add MAP_BORDER * 2
+ ld e, a
+ ld d, 0
+ ld b, 0
+ add hl, de
dec c
- jr nz,.pointerAdjustmentLoop2
+ jr nz, .pointerAdjustmentLoop2
.savePointer2
- ld a,l
- ld [wCurrentTileBlockMapViewPointer],a ; pointer to upper left corner of current tile block map section
- ld a,h
- ld [wCurrentTileBlockMapViewPointer + 1],a
+ ld a, l
+ ld [wCurrentTileBlockMapViewPointer], a ; pointer to upper left corner of current tile block map section
+ ld a, h
+ ld [wCurrentTileBlockMapViewPointer + 1], a
jp .loadNewMap
+
.checkNorthMap
- ld a,[wYCoord]
- cp a,$ff
- jr nz,.checkSouthMap
- ld a,[wMapConn1Ptr]
- ld [wCurMap],a
- ld a,[wNorthConnectedMapYAlignment] ; new Y coordinate upon entering north map
- ld [wYCoord],a
- ld a,[wXCoord]
- ld c,a
- ld a,[wNorthConnectedMapXAlignment] ; X adjustment upon entering north map
+ ld a, [wYCoord]
+ cp $ff
+ jr nz, .checkSouthMap
+ ld a, [wMapConn1Ptr]
+ ld [wCurMap], a
+ ld a, [wNorthConnectedMapYAlignment] ; new Y coordinate upon entering north map
+ ld [wYCoord], a
+ ld a, [wXCoord]
+ ld c, a
+ ld a, [wNorthConnectedMapXAlignment] ; X adjustment upon entering north map
add c
- ld c,a
- ld [wXCoord],a
- ld a,[wNorthConnectedMapViewPointer] ; pointer to upper left corner of map without adjustment for X position
- ld l,a
- ld a,[wNorthConnectedMapViewPointer + 1]
- ld h,a
- ld b,0
+ ld c, a
+ ld [wXCoord], a
+ ld a, [wNorthConnectedMapViewPointer] ; pointer to upper left corner of map without adjustment for X position
+ ld l, a
+ ld a, [wNorthConnectedMapViewPointer + 1]
+ ld h, a
+ ld b, 0
srl c
- add hl,bc
- ld a,l
- ld [wCurrentTileBlockMapViewPointer],a ; pointer to upper left corner of current tile block map section
- ld a,h
- ld [wCurrentTileBlockMapViewPointer + 1],a
+ add hl, bc
+ ld a, l
+ ld [wCurrentTileBlockMapViewPointer], a ; pointer to upper left corner of current tile block map section
+ ld a, h
+ ld [wCurrentTileBlockMapViewPointer + 1], a
jp .loadNewMap
+
.checkSouthMap
- ld b,a
- ld a,[wCurrentMapHeight2]
+ ld b, a
+ ld a, [wCurrentMapHeight2]
cp b
- jr nz,.didNotEnterConnectedMap
- ld a,[wMapConn2Ptr]
- ld [wCurMap],a
- ld a,[wSouthConnectedMapYAlignment] ; new Y coordinate upon entering south map
- ld [wYCoord],a
- ld a,[wXCoord]
- ld c,a
- ld a,[wSouthConnectedMapXAlignment] ; X adjustment upon entering south map
+ jr nz, .didNotEnterConnectedMap
+ ld a, [wMapConn2Ptr]
+ ld [wCurMap], a
+ ld a, [wSouthConnectedMapYAlignment] ; new Y coordinate upon entering south map
+ ld [wYCoord], a
+ ld a, [wXCoord]
+ ld c, a
+ ld a, [wSouthConnectedMapXAlignment] ; X adjustment upon entering south map
add c
- ld c,a
- ld [wXCoord],a
- ld a,[wSouthConnectedMapViewPointer] ; pointer to upper left corner of map without adjustment for X position
- ld l,a
- ld a,[wSouthConnectedMapViewPointer + 1]
- ld h,a
- ld b,0
+ ld c, a
+ ld [wXCoord], a
+ ld a, [wSouthConnectedMapViewPointer] ; pointer to upper left corner of map without adjustment for X position
+ ld l, a
+ ld a, [wSouthConnectedMapViewPointer + 1]
+ ld h, a
+ ld b, 0
srl c
- add hl,bc
- ld a,l
- ld [wCurrentTileBlockMapViewPointer],a ; pointer to upper left corner of current tile block map section
- ld a,h
- ld [wCurrentTileBlockMapViewPointer + 1],a
-.loadNewMap ; load the connected map that was entered
- call LoadMapHeader
- call PlayDefaultMusicFadeOutCurrent
+ add hl, bc
+ ld a, l
+ ld [wCurrentTileBlockMapViewPointer], a ; pointer to upper left corner of current tile block map section
+ ld a, h
+ ld [wCurrentTileBlockMapViewPointer + 1], a
+.loadNewMap ; 06ce (0:06ce)
+; load the connected map that was entered
+ ld hl, wPikachuOverworldStateFlags
+ set 4, [hl]
+ ld a, $2
+ ld [wPikachuSpawnState], a
+ call LoadMapHeader ; 0dab (0:0dab)
+ call PlayDefaultMusicFadeOutCurrent ; music
ld b, SET_PAL_OVERWORLD
call RunPaletteCommand
; Since the sprite set shouldn't change, this will just update VRAM slots at
; $C2XE without loading any tile patterns.
- callba InitMapSprites
+ call InitMapSprites
call LoadTileBlockMap
jp OverworldLoopLessDelay
+
.didNotEnterConnectedMap
jp OverworldLoop
; function to play a sound when changing maps
PlayMapChangeSound::
+ ld a, [wCurMapTileset]
+ cp FACILITY
+ jr z, .didNotGoThroughDoor
+ cp CEMETERY
+ jr z, .didNotGoThroughDoor
aCoord 8, 8 ; upper left tile of the 4x4 square the player's sprite is standing on
- cp a,$0b ; door tile in tileset 0
- jr nz,.didNotGoThroughDoor
- ld a,SFX_GO_INSIDE
+ cp UNDERGROUND ; door tile in tileset 0
+ jr nz, .didNotGoThroughDoor
+ ld a, $ad ; SFX_GO_INSIDE
jr .playSound
+
.didNotGoThroughDoor
- ld a,SFX_GO_OUTSIDE
+ ld a, $b5 ; SFX_GO_OUTSIDE
.playSound
call PlaySound
- ld a,[wMapPalOffset]
+ ld a, [wMapPalOffset]
and a
ret nz
jp GBFadeOutToBlack
@@ -723,6 +732,7 @@ ExtraWarpCheck::
.useFunction1
ld hl, IsPlayerFacingEdgeOfMap
jr .doBankswitch
+
.useFunction2
ld hl, IsWarpTileInFrontOfPlayer
.doBankswitch
@@ -731,9 +741,9 @@ ExtraWarpCheck::
MapEntryAfterBattle::
callba IsPlayerStandingOnWarp ; for enabling warp testing after collisions
- ld a,[wMapPalOffset]
+ ld a, [wMapPalOffset]
and a
- jp z,GBFadeInFromWhite
+ jp z, GBFadeInFromWhite
jp LoadGBPal
HandleBlackOut::
@@ -745,19 +755,15 @@ HandleBlackOut::
call StopMusic
ld hl, wd72e
res 5, [hl]
- ld a, Bank(ResetStatusAndHalveMoneyOnBlackout) ; also Bank(SpecialWarpIn) and Bank(SpecialEnterMap)
- ld [H_LOADEDROMBANK], a
- ld [MBC1RomBank], a
- call ResetStatusAndHalveMoneyOnBlackout
+ switchbank SpecialWarpIn ; also Bank(SpecialEnterMap)
+ callab ResetStatusAndHalveMoneyOnBlackout ; 3c:4274
call SpecialWarpIn
call PlayDefaultMusicFadeOutCurrent
jp SpecialEnterMap
StopMusic::
ld [wAudioFadeOutControl], a
- ld a, $ff
- ld [wNewSoundID], a
- call PlaySound
+ call StopAllMusic
.wait
ld a, [wAudioFadeOutControl]
and a
@@ -769,22 +775,31 @@ HandleFlyWarpOrDungeonWarp::
call Delay3
xor a
ld [wBattleResult], a
- ld [wWalkBikeSurfState], a
ld [wIsInBattle], a
ld [wMapPalOffset], a
ld hl, wd732
set 2, [hl] ; fly warp or dungeon warp
res 5, [hl] ; forced to ride bike
call LeaveMapAnim
- ld a, Bank(SpecialWarpIn)
- ld [H_LOADEDROMBANK], a
- ld [MBC1RomBank], a
- call SpecialWarpIn
+ call Func_07c4
+ callbs SpecialWarpIn
jp SpecialEnterMap
LeaveMapAnim::
jpba _LeaveMapAnim
+Func_07c4::
+ ld a, [wWalkBikeSurfState]
+ and a
+ ret z
+ xor a
+ ld [wWalkBikeSurfState], a
+ ld hl, wd732
+ bit 4, [hl]
+ ret z
+ call PlayDefaultMusic
+ ret
+
LoadPlayerSpriteGraphics::
; Load sprite graphics based on whether the player is standing, biking, or surfing.
@@ -820,7 +835,7 @@ LoadPlayerSpriteGraphics::
dec a
jp z, LoadBikePlayerSpriteGraphics
dec a
- jp z, LoadSurfingPlayerSpriteGraphics
+ jp z, LoadSurfingPlayerSpriteGraphics2
jp LoadWalkingPlayerSpriteGraphics
IsBikeRidingAllowed::
@@ -854,384 +869,412 @@ INCLUDE "data/bike_riding_tilesets.asm"
; load the tile pattern data of the current tileset into VRAM
LoadTilesetTilePatternData::
- ld a,[wTileSetGFXPtr]
- ld l,a
- ld a,[wTileSetGFXPtr + 1]
- ld h,a
- ld de,vTileset
- ld bc,$600
- ld a,[wTileSetBank]
- jp FarCopyData2
+ ld a, [wTilesetGFXPtr]
+ ld l, a
+ ld a, [wTilesetGFXPtr + 1]
+ ld h, a
+ ld de, vTileset
+ ld bc, $600
+ ld a, [wTilesetBank]
+ jp FarCopyData
; this loads the current maps complete tile map (which references blocks, not individual tiles) to C6E8
; it can also load partial tile maps of connected maps into a border of length 3 around the current map
LoadTileBlockMap::
; fill C6E8-CBFB with the background tile
- ld hl,wOverworldMap
- ld a,[wMapBackgroundTile]
- ld d,a
- ld bc,$0514
-.backgroundTileLoop
- ld a,d
- ld [hli],a
- dec bc
- ld a,c
- or b
- jr nz,.backgroundTileLoop
+ ld hl, wOverworldMap
+ ld bc, $0514
+ ld a, [wMapBackgroundTile] ; background tile number
+ call FillMemory
; load tile map of current map (made of tile block IDs)
; a 3-byte border at the edges of the map is kept so that there is space for map connections
- ld hl,wOverworldMap
- ld a,[wCurMapWidth]
- ld [hMapWidth],a
- add a,MAP_BORDER * 2 ; east and west
- ld [hMapStride],a ; map width + border
- ld b,0
- ld c,a
+ ld hl, wOverworldMap
+ ld a, [wCurMapWidth]
+ ld [hMapWidth], a
+ add MAP_BORDER * 2 ; east and west
+ ld [hMapStride], a ; map width + border
+ ld b, 0
+ ld c, a
; make space for north border (next 3 lines)
- add hl,bc
- add hl,bc
- add hl,bc
- ld c,MAP_BORDER
- add hl,bc ; this puts us past the (west) border
- ld a,[wMapDataPtr] ; tile map pointer
- ld e,a
- ld a,[wMapDataPtr + 1]
- ld d,a ; de = tile map pointer
- ld a,[wCurMapHeight]
- ld b,a
+ add hl, bc
+ add hl, bc
+ add hl, bc
+ ld c, MAP_BORDER
+ add hl, bc ; this puts us past the (west) border
+ ld a, [wMapDataPtr] ; tile map pointer
+ ld e, a
+ ld a, [wMapDataPtr + 1]
+ ld d, a ; de = tile map pointer
+ ld a, [wCurMapHeight]
+ ld b, a
.rowLoop ; copy one row each iteration
push hl
- ld a,[hMapWidth] ; map width (without border)
- ld c,a
+ ld a, [hMapWidth] ; map width (without border)
+ ld c, a
.rowInnerLoop
- ld a,[de]
+ ld a, [de]
inc de
- ld [hli],a
+ ld [hli], a
dec c
- jr nz,.rowInnerLoop
+ jr nz, .rowInnerLoop
; add the map width plus the border to the base address of the current row to get the next row's address
pop hl
- ld a,[hMapStride] ; map width + border
+ ld a, [hMapStride] ; map width + border
add l
- ld l,a
- jr nc,.noCarry
+ ld l, a
+ jr nc, .noCarry
inc h
.noCarry
dec b
- jr nz,.rowLoop
+ jr nz, .rowLoop
.northConnection
- ld a,[wMapConn1Ptr]
- cp a,$ff
- jr z,.southConnection
+ ld a, [wMapConn1Ptr]
+ cp $ff
+ jr z, .southConnection
call SwitchToMapRomBank
- ld a,[wNorthConnectionStripSrc]
- ld l,a
- ld a,[wNorthConnectionStripSrc + 1]
- ld h,a
- ld a,[wNorthConnectionStripDest]
- ld e,a
- ld a,[wNorthConnectionStripDest + 1]
- ld d,a
- ld a,[wNorthConnectionStripWidth]
- ld [hNorthSouthConnectionStripWidth],a
- ld a,[wNorthConnectedMapWidth]
- ld [hNorthSouthConnectedMapWidth],a
+ ld a, [wNorthConnectionStripSrc]
+ ld l, a
+ ld a, [wNorthConnectionStripSrc + 1]
+ ld h, a
+ ld a, [wNorthConnectionStripDest]
+ ld e, a
+ ld a, [wNorthConnectionStripDest + 1]
+ ld d, a
+ ld a, [wNorthConnectionStripWidth]
+ ld [hNorthSouthConnectionStripWidth], a
+ ld a, [wNorthConnectedMapWidth]
+ ld [hNorthSouthConnectedMapWidth], a
call LoadNorthSouthConnectionsTileMap
.southConnection
- ld a,[wMapConn2Ptr]
- cp a,$ff
- jr z,.westConnection
+ ld a, [wMapConn2Ptr]
+ cp $ff
+ jr z, .westConnection
call SwitchToMapRomBank
- ld a,[wSouthConnectionStripSrc]
- ld l,a
- ld a,[wSouthConnectionStripSrc + 1]
- ld h,a
- ld a,[wSouthConnectionStripDest]
- ld e,a
- ld a,[wSouthConnectionStripDest + 1]
- ld d,a
- ld a,[wSouthConnectionStripWidth]
- ld [hNorthSouthConnectionStripWidth],a
- ld a,[wSouthConnectedMapWidth]
- ld [hNorthSouthConnectedMapWidth],a
+ ld a, [wSouthConnectionStripSrc]
+ ld l, a
+ ld a, [wSouthConnectionStripSrc + 1]
+ ld h, a
+ ld a, [wSouthConnectionStripDest]
+ ld e, a
+ ld a, [wSouthConnectionStripDest + 1]
+ ld d, a
+ ld a, [wSouthConnectionStripWidth]
+ ld [hNorthSouthConnectionStripWidth], a
+ ld a, [wSouthConnectedMapWidth]
+ ld [hNorthSouthConnectedMapWidth], a
call LoadNorthSouthConnectionsTileMap
.westConnection
- ld a,[wMapConn3Ptr]
- cp a,$ff
- jr z,.eastConnection
+ ld a, [wMapConn3Ptr]
+ cp $ff
+ jr z, .eastConnection
call SwitchToMapRomBank
- ld a,[wWestConnectionStripSrc]
- ld l,a
- ld a,[wWestConnectionStripSrc + 1]
- ld h,a
- ld a,[wWestConnectionStripDest]
- ld e,a
- ld a,[wWestConnectionStripDest + 1]
- ld d,a
- ld a,[wWestConnectionStripHeight]
- ld b,a
- ld a,[wWestConnectedMapWidth]
- ld [hEastWestConnectedMapWidth],a
+ ld a, [wWestConnectionStripSrc]
+ ld l, a
+ ld a, [wWestConnectionStripSrc + 1]
+ ld h, a
+ ld a, [wWestConnectionStripDest]
+ ld e, a
+ ld a, [wWestConnectionStripDest + 1]
+ ld d, a
+ ld a, [wWestConnectionStripHeight]
+ ld b, a
+ ld a, [wWestConnectedMapWidth]
+ ld [hEastWestConnectedMapWidth], a
call LoadEastWestConnectionsTileMap
.eastConnection
- ld a,[wMapConn4Ptr]
- cp a,$ff
- jr z,.done
+ ld a, [wMapConn4Ptr]
+ cp $ff
+ jr z, .done
call SwitchToMapRomBank
- ld a,[wEastConnectionStripSrc]
- ld l,a
- ld a,[wEastConnectionStripSrc + 1]
- ld h,a
- ld a,[wEastConnectionStripDest]
- ld e,a
- ld a,[wEastConnectionStripDest + 1]
- ld d,a
- ld a,[wEastConnectionStripHeight]
- ld b,a
- ld a,[wEastConnectedMapWidth]
- ld [hEastWestConnectedMapWidth],a
+ ld a, [wEastConnectionStripSrc]
+ ld l, a
+ ld a, [wEastConnectionStripSrc + 1]
+ ld h, a
+ ld a, [wEastConnectionStripDest]
+ ld e, a
+ ld a, [wEastConnectionStripDest + 1]
+ ld d, a
+ ld a, [wEastConnectionStripHeight]
+ ld b, a
+ ld a, [wEastConnectedMapWidth]
+ ld [hEastWestConnectedMapWidth], a
call LoadEastWestConnectionsTileMap
.done
ret
LoadNorthSouthConnectionsTileMap::
- ld c,MAP_BORDER
+ ld c, MAP_BORDER
.loop
push de
push hl
- ld a,[hNorthSouthConnectionStripWidth]
- ld b,a
+ ld a, [hNorthSouthConnectionStripWidth]
+ ld b, a
.innerLoop
- ld a,[hli]
- ld [de],a
+ ld a, [hli]
+ ld [de], a
inc de
dec b
- jr nz,.innerLoop
+ jr nz, .innerLoop
pop hl
pop de
- ld a,[hNorthSouthConnectedMapWidth]
+ ld a, [hNorthSouthConnectedMapWidth]
add l
- ld l,a
- jr nc,.noCarry1
+ ld l, a
+ jr nc, .noCarry1
inc h
.noCarry1
- ld a,[wCurMapWidth]
- add a,MAP_BORDER * 2
+ ld a, [wCurMapWidth]
+ add MAP_BORDER * 2
add e
- ld e,a
- jr nc,.noCarry2
+ ld e, a
+ jr nc, .noCarry2
inc d
.noCarry2
dec c
- jr nz,.loop
+ jr nz, .loop
ret
LoadEastWestConnectionsTileMap::
push hl
push de
- ld c,MAP_BORDER
+ ld c, MAP_BORDER
.innerLoop
- ld a,[hli]
- ld [de],a
+ ld a, [hli]
+ ld [de], a
inc de
dec c
- jr nz,.innerLoop
+ jr nz, .innerLoop
pop de
pop hl
- ld a,[hEastWestConnectedMapWidth]
+ ld a, [hEastWestConnectedMapWidth]
add l
- ld l,a
- jr nc,.noCarry1
+ ld l, a
+ jr nc, .noCarry1
inc h
.noCarry1
- ld a,[wCurMapWidth]
- add a,MAP_BORDER * 2
+ ld a, [wCurMapWidth]
+ add MAP_BORDER * 2
add e
- ld e,a
- jr nc,.noCarry2
+ ld e, a
+ jr nc, .noCarry2
inc d
.noCarry2
dec b
- jr nz,LoadEastWestConnectionsTileMap
+ jr nz, LoadEastWestConnectionsTileMap
ret
; function to check if there is a sign or sprite in front of the player
-; if so, it is stored in [hSpriteIndexOrTextID]
-; if not, [hSpriteIndexOrTextID] is set to 0
+; if so, carry is set. otherwise, carry is cleared
IsSpriteOrSignInFrontOfPlayer::
xor a
- ld [hSpriteIndexOrTextID],a
- ld a,[wNumSigns]
+ ld [hSpriteIndexOrTextID], a
+ ld a, [wNumSigns]
and a
- jr z,.extendRangeOverCounter
+ jr z, .extendRangeOverCounter
; if there are signs
predef GetTileAndCoordsInFrontOfPlayer ; get the coordinates in front of the player in de
- ld hl,wSignCoords
- ld a,[wNumSigns]
- ld b,a
- ld c,0
-.signLoop
- inc c
- ld a,[hli] ; sign Y
- cp d
- jr z,.yCoordMatched
- inc hl
- jr .retry
-.yCoordMatched
- ld a,[hli] ; sign X
- cp e
- jr nz,.retry
-.xCoordMatched
-; found sign
- push hl
- push bc
- ld hl,wSignTextIDs
- ld b,0
- dec c
- add hl,bc
- ld a,[hl]
- ld [hSpriteIndexOrTextID],a ; store sign text ID
- pop bc
- pop hl
- ret
-.retry
- dec b
- jr nz,.signLoop
-; check if the player is front of a counter in a pokemon center, pokemart, etc. and if so, extend the range at which he can talk to the NPC
+ call SignLoop
+ ret c
.extendRangeOverCounter
+; check if the player is front of a counter in a pokemon center, pokemart, etc. and if so, extend the range at which he can talk to the NPC
predef GetTileAndCoordsInFrontOfPlayer ; get the tile in front of the player in c
- ld hl,wTileSetTalkingOverTiles ; list of tiles that extend talking range (counter tiles)
- ld b,3
- ld d,$20 ; talking range in pixels (long range)
+ ld hl, wTileSetTalkingOverTiles ; list of tiles that extend talking range (counter tiles)
+ ld b, 3
+ ld d, $20 ; talking range in pixels (long range)
.counterTilesLoop
- ld a,[hli]
+ ld a, [hli]
cp c
- jr z,IsSpriteInFrontOfPlayer2 ; jumps if the tile in front of the player is a counter tile
+ jr z, IsSpriteInFrontOfPlayer2 ; jumps if the tile in front of the player is a counter tile
dec b
- jr nz,.counterTilesLoop
+ jr nz, .counterTilesLoop
-; part of the above function, but sometimes its called on its own, when signs are irrelevant
-; the caller must zero [hSpriteIndexOrTextID]
+; sets carry flag if a sprite is in front of the player, resets if not
IsSpriteInFrontOfPlayer::
- ld d,$10 ; talking range in pixels (normal range)
+ ld d, $10 ; talking range in pixels (normal range)
IsSpriteInFrontOfPlayer2::
lb bc, $3c, $40 ; Y and X position of player sprite
- ld a,[wSpriteStateData1 + 9] ; direction the player is facing
+ ld a, [wPlayerFacingDirection] ; direction the player is facing
.checkIfPlayerFacingUp
cp SPRITE_FACING_UP
- jr nz,.checkIfPlayerFacingDown
+ jr nz, .checkIfPlayerFacingDown
; facing up
- ld a,b
+ ld a, b
sub d
- ld b,a
- ld a,PLAYER_DIR_UP
+ ld b, a
+ ld a, PLAYER_DIR_UP
jr .doneCheckingDirection
+
.checkIfPlayerFacingDown
cp SPRITE_FACING_DOWN
- jr nz,.checkIfPlayerFacingRight
+ jr nz, .checkIfPlayerFacingRight
; facing down
- ld a,b
+ ld a, b
add d
- ld b,a
- ld a,PLAYER_DIR_DOWN
+ ld b, a
+ ld a, PLAYER_DIR_DOWN
jr .doneCheckingDirection
+
.checkIfPlayerFacingRight
cp SPRITE_FACING_RIGHT
- jr nz,.playerFacingLeft
+ jr nz, .playerFacingLeft
; facing right
- ld a,c
+ ld a, c
add d
- ld c,a
- ld a,PLAYER_DIR_RIGHT
+ ld c, a
+ ld a, PLAYER_DIR_RIGHT
jr .doneCheckingDirection
+
.playerFacingLeft
; facing left
- ld a,c
+ ld a, c
sub d
- ld c,a
- ld a,PLAYER_DIR_LEFT
+ ld c, a
+ ld a, PLAYER_DIR_LEFT
.doneCheckingDirection
- ld [wPlayerDirection],a
- ld a,[wNumSprites] ; number of sprites
- and a
- ret z
-; if there are sprites
- ld hl,wSpriteStateData1 + $10
- ld d,a
- ld e,$01
+ ld [wPlayerDirection], a
+ ld hl, wSpriteStateData1 + $10
+; yellow does not have the "if sprites are existant" check
+ ld e, $01
+ ld d, $f
.spriteLoop
push hl
- ld a,[hli] ; image (0 if no sprite)
+ ld a, [hli] ; image (0 if no sprite)
and a
- jr z,.nextSprite
+ jr z, .nextSprite
inc l
- ld a,[hli] ; sprite visibility
+ ld a, [hli] ; sprite visibility
inc a
- jr z,.nextSprite
+ jr z, .nextSprite
inc l
- ld a,[hli] ; Y location
+ ld a, [hli] ; Y location
cp b
- jr nz,.nextSprite
+ jr nz, .nextSprite
inc l
- ld a,[hl] ; X location
+ ld a, [hl] ; X location
cp c
- jr z,.foundSpriteInFrontOfPlayer
+ jr z, .foundSpriteInFrontOfPlayer
.nextSprite
pop hl
- ld a,l
- add a,$10
- ld l,a
+ ld a, l
+ add $10
+ ld l, a
inc e
dec d
- jr nz,.spriteLoop
+ jr nz, .spriteLoop
+ xor a
ret
+
.foundSpriteInFrontOfPlayer
pop hl
- ld a,l
- and a,$f0
+ ld a, l
+ and $f0
inc a
- ld l,a ; hl = $c1x1
- set 7,[hl] ; set flag to make the sprite face the player
- ld a,e
- ld [hSpriteIndexOrTextID],a
+ ld l, a ; hl = $c1x1
+ set 7, [hl] ; set flag to make the sprite face the player
+ ld a, e
+ ld [hSpriteIndexOrTextID], a
+ ld a, [hSpriteIndexOrTextID] ; possible useless read because a already has the value of the read address
+ cp $f
+ jr nz, .dontwritetowd436
+ ld a, $FF
+ ld [wd436], a
+.dontwritetowd436
+ scf
+ ret
+
+SignLoop::
+; search if a player is facing a sign
+ ld hl, wSignCoords ; start of sign coordinates
+ ld a, [wNumSigns] ; number of signs in the map
+ ld b, a
+ ld c, $00
+.signLoop
+ inc c
+ ld a, [hli] ; sign Y
+ cp d
+ jr z, .yCoordMatched
+ inc hl
+ jr .retry
+
+.yCoordMatched
+ ld a, [hli] ; sign X
+ cp e
+ jr nz, .retry
+.xCoordMatched
+; found sign
+ push hl
+ push bc
+ ld hl, wSignTextIDs ; start of sign text ID's
+ ld b, $00
+ dec c
+ add hl, bc
+ ld a, [hl]
+ ld [hSpriteIndexOrTextID], a ; store sign text ID
+ pop bc
+ pop hl
+ scf
+ ret
+
+.retry
+ dec b
+ jr nz, .signLoop
+ xor a
ret
; function to check if the player will jump down a ledge and check if the tile ahead is passable (when not surfing)
; sets the carry flag if there is a collision, and unsets it if there isn't a collision
CollisionCheckOnLand::
- ld a,[wd736]
- bit 6,a ; is the player jumping?
- jr nz,.noCollision
+ ld a, [wd736]
+ bit 6, a ; is the player jumping?
+ jr nz, .noCollision
; if not jumping a ledge
- ld a,[wSimulatedJoypadStatesIndex]
+ ld a, [wSimulatedJoypadStatesIndex]
and a
- jr nz,.noCollision ; no collisions when the player's movements are being controlled by the game
- ld a,[wPlayerDirection] ; the direction that the player is trying to go in
- ld d,a
- ld a,[wSpriteStateData1 + 12] ; the player sprite's collision data (bit field) (set in the sprite movement code)
+ jr nz, .noCollision ; no collisions when the player's movements are being controlled by the game
+ ld a, [wPlayerDirection] ; the direction that the player is trying to go in
+ ld d, a
+ ld a, [wSpriteStateData1 + 12] ; the player sprite's collision data (bit field) (set in the sprite movement code)
and d ; check if a sprite is in the direction the player is trying to go
- jr nz,.collision
+ nop ; ??? why is this in the code
+ jr nz, .collision
xor a
- ld [hSpriteIndexOrTextID],a
+ ld [hSpriteIndexOrTextID], a
call IsSpriteInFrontOfPlayer ; check for sprite collisions again? when does the above check fail to detect a sprite collision?
- ld a,[hSpriteIndexOrTextID]
+ jr nc, .asm_0a5c
+ res 7, [hl]
+ ld a, [hSpriteIndexOrTextID]
and a ; was there a sprite collision?
- jr nz,.collision
+ jr z, .asm_0a5c
; if no sprite collision
- ld hl,TilePairCollisionsLand
+ cp $f
+ jr nz, .collision
+ call CheckPikachuFollowingPlayer
+ jr nz, .collision
+ ld a, [hJoyHeld]
+ and $2
+ jr nz, .asm_0a5c
+ ld hl, wd435
+ ld a, [hl]
+ and a
+ jr z, .asm_0a5c
+ dec [hl]
+ jr nz, .collision
+.asm_0a5c
+ ld hl, TilePairCollisionsLand
call CheckForJumpingAndTilePairCollisions
- jr c,.collision
+ jr c, .collision
call CheckTilePassable
- jr nc,.noCollision
+ jr nc, .noCollision
.collision
- ld a,[wChannelSoundIDs + CH4]
- cp a,SFX_COLLISION ; check if collision sound is already playing
- jr z,.setCarry
- ld a,SFX_COLLISION
+ ld a, [wChannelSoundIDs + CH4]
+ cp $b4 ; SFX_COLLISION ; check if collision sound is already playing
+ jr z, .setCarry
+ ld a, $b4 ; SFX_COLLISION
call PlaySound ; play collision sound (if it's not already playing)
.setCarry
scf
ret
+
.noCollision
and a
ret
@@ -1240,21 +1283,9 @@ CollisionCheckOnLand::
; clears carry if it is, sets carry if not
CheckTilePassable::
predef GetTileAndCoordsInFrontOfPlayer ; get tile in front of player
- ld a,[wTileInFrontOfPlayer] ; tile in front of player
- ld c,a
- ld hl,wTileSetCollisionPtr ; pointer to list of passable tiles
- ld a,[hli]
- ld h,[hl]
- ld l,a ; hl now points to passable tiles
-.loop
- ld a,[hli]
- cp a,$ff
- jr z,.tileNotPassable
- cp c
- ret z
- jr .loop
-.tileNotPassable
- scf
+ ld a, [wTileInFrontOfPlayer] ; tile in front of player
+ ld c, a
+ call IsTilePassable
ret
; check if the player is going to jump down a small ledge
@@ -1266,61 +1297,66 @@ CheckForJumpingAndTilePairCollisions::
predef GetTileAndCoordsInFrontOfPlayer ; get the tile in front of the player
push de
push bc
- callba HandleLedges ; check if the player is trying to jump a ledge
+ callba HandleLedges ; 6:67f4
+ ; check if the player is trying to jump a ledge
pop bc
pop de
pop hl
and a
- ld a,[wd736]
- bit 6,a ; is the player jumping?
+ ld a, [wd736]
+ bit 6, a ; is the player jumping?
ret nz
; if not jumping
CheckForTilePairCollisions2::
aCoord 8, 9 ; tile the player is on
- ld [wTilePlayerStandingOn],a
+ ld [wTilePlayerStandingOn], a
CheckForTilePairCollisions::
- ld a,[wTileInFrontOfPlayer]
- ld c,a
+ ld a, [wTileInFrontOfPlayer]
+ ld c, a
.tilePairCollisionLoop
- ld a,[wCurMapTileset] ; tileset number
- ld b,a
- ld a,[hli]
- cp a,$ff
- jr z,.noMatch
+ ld a, [wCurMapTileset] ; tileset number
+ ld b, a
+ ld a, [hli]
+ cp $ff
+ jr z, .noMatch
cp b
- jr z,.tilesetMatches
+ jr z, .tilesetMatches
inc hl
.retry
inc hl
jr .tilePairCollisionLoop
+
.tilesetMatches
- ld a,[wTilePlayerStandingOn] ; tile the player is on
- ld b,a
- ld a,[hl]
+ ld a, [wTilePlayerStandingOn] ; tile the player is on
+ ld b, a
+ ld a, [hl]
cp b
- jr z,.currentTileMatchesFirstInPair
+ jr z, .currentTileMatchesFirstInPair
inc hl
- ld a,[hl]
+ ld a, [hl]
cp b
- jr z,.currentTileMatchesSecondInPair
+ jr z, .currentTileMatchesSecondInPair
jr .retry
+
.currentTileMatchesFirstInPair
inc hl
- ld a,[hl]
+ ld a, [hl]
cp c
- jr z,.foundMatch
+ jr z, .foundMatch
jr .tilePairCollisionLoop
+
.currentTileMatchesSecondInPair
dec hl
- ld a,[hli]
+ ld a, [hli]
cp c
inc hl
- jr nz,.tilePairCollisionLoop
+ jr nz, .tilePairCollisionLoop
.foundMatch
scf
ret
+
.noMatch
and a
ret
@@ -1352,27 +1388,26 @@ TilePairCollisionsWater::
; this builds a tile map from the tile block map based on the current X/Y coordinates of the player's character
LoadCurrentMapView::
- ld a,[H_LOADEDROMBANK]
+ ld a, [H_LOADEDROMBANK]
push af
- ld a,[wTileSetBank] ; tile data ROM bank
- ld [H_LOADEDROMBANK],a
- ld [MBC1RomBank],a ; switch to ROM bank that contains tile data
- ld a,[wCurrentTileBlockMapViewPointer] ; address of upper left corner of current map view
- ld e,a
- ld a,[wCurrentTileBlockMapViewPointer + 1]
- ld d,a
- ld hl,wTileMapBackup
- ld b,$05
+ ld a, [wTilesetBank] ; tile data ROM bank
+ call BankswitchCommon ; switch to ROM bank that contains tile data
+ ld a, [wCurrentTileBlockMapViewPointer] ; address of upper left corner of current map view
+ ld e, a
+ ld a, [wCurrentTileBlockMapViewPointer + 1]
+ ld d, a
+ ld hl, wTileMapBackup
+ ld b, $05
.rowLoop ; each loop iteration fills in one row of tile blocks
push hl
push de
- ld c,$06
+ ld c, $06
.rowInnerLoop ; loop to draw each tile block of the current row
push bc
push de
push hl
- ld a,[de]
- ld c,a ; tile block number
+ ld a, [de]
+ ld c, a ; tile block number
call DrawTileBlock
pop hl
pop de
@@ -1383,308 +1418,73 @@ LoadCurrentMapView::
inc hl
inc de
dec c
- jr nz,.rowInnerLoop
+ jr nz, .rowInnerLoop
; update tile block map pointer to next row's address
pop de
- ld a,[wCurMapWidth]
- add a,MAP_BORDER * 2
+ ld a, [wCurMapWidth]
+ add MAP_BORDER * 2
add e
- ld e,a
- jr nc,.noCarry
+ ld e, a
+ jr nc, .noCarry
inc d
.noCarry
; update tile map pointer to next row's address
pop hl
- ld a,$60
+ ld a, $60
add l
- ld l,a
- jr nc,.noCarry2
+ ld l, a
+ jr nc, .noCarry2
inc h
.noCarry2
dec b
- jr nz,.rowLoop
- ld hl,wTileMapBackup
- ld bc,$0000
+ jr nz, .rowLoop
+ ld hl, wTileMapBackup
+ ld bc, $0000
.adjustForYCoordWithinTileBlock
- ld a,[wYBlockCoord]
+ ld a, [wYBlockCoord]
and a
- jr z,.adjustForXCoordWithinTileBlock
- ld bc,$0030
- add hl,bc
+ jr z, .adjustForXCoordWithinTileBlock
+ ld bc, $0030
+ add hl, bc
.adjustForXCoordWithinTileBlock
- ld a,[wXBlockCoord]
+ ld a, [wXBlockCoord]
and a
- jr z,.copyToVisibleAreaBuffer
- ld bc,$0002
- add hl,bc
+ jr z, .copyToVisibleAreaBuffer
+ ld bc, $0002
+ add hl, bc
.copyToVisibleAreaBuffer
coord de, 0, 0 ; base address for the tiles that are directly transferred to VRAM during V-blank
ld b, SCREEN_HEIGHT
.rowLoop2
ld c, SCREEN_WIDTH
.rowInnerLoop2
- ld a,[hli]
- ld [de],a
+ ld a, [hli]
+ ld [de], a
inc de
dec c
- jr nz,.rowInnerLoop2
- ld a,$04
+ jr nz, .rowInnerLoop2
+ ld a, $04
add l
- ld l,a
- jr nc,.noCarry3
+ ld l, a
+ jr nc, .noCarry3
inc h
.noCarry3
dec b
- jr nz,.rowLoop2
+ jr nz, .rowLoop2
pop af
- ld [H_LOADEDROMBANK],a
- ld [MBC1RomBank],a ; restore previous ROM bank
+ call BankswitchCommon ; restore previous ROM bank
ret
AdvancePlayerSprite::
- ld a,[wSpriteStateData1 + 3] ; delta Y
- ld b,a
- ld a,[wSpriteStateData1 + 5] ; delta X
- ld c,a
- ld hl,wWalkCounter ; walking animation counter
- dec [hl]
- jr nz,.afterUpdateMapCoords
-; if it's the end of the animation, update the player's map coordinates
- ld a,[wYCoord]
- add b
- ld [wYCoord],a
- ld a,[wXCoord]
- add c
- ld [wXCoord],a
-.afterUpdateMapCoords
- ld a,[wWalkCounter] ; walking animation counter
- cp a,$07
- jp nz,.scrollBackgroundAndSprites
-; if this is the first iteration of the animation
- ld a,c
- cp a,$01
- jr nz,.checkIfMovingWest
-; moving east
- ld a,[wMapViewVRAMPointer]
- ld e,a
- and a,$e0
- ld d,a
- ld a,e
- add a,$02
- and a,$1f
- or d
- ld [wMapViewVRAMPointer],a
- jr .adjustXCoordWithinBlock
-.checkIfMovingWest
- cp a,$ff
- jr nz,.checkIfMovingSouth
-; moving west
- ld a,[wMapViewVRAMPointer]
- ld e,a
- and a,$e0
- ld d,a
- ld a,e
- sub a,$02
- and a,$1f
- or d
- ld [wMapViewVRAMPointer],a
- jr .adjustXCoordWithinBlock
-.checkIfMovingSouth
- ld a,b
- cp a,$01
- jr nz,.checkIfMovingNorth
-; moving south
- ld a,[wMapViewVRAMPointer]
- add a,$40
- ld [wMapViewVRAMPointer],a
- jr nc,.adjustXCoordWithinBlock
- ld a,[wMapViewVRAMPointer + 1]
- inc a
- and a,$03
- or a,$98
- ld [wMapViewVRAMPointer + 1],a
- jr .adjustXCoordWithinBlock
-.checkIfMovingNorth
- cp a,$ff
- jr nz,.adjustXCoordWithinBlock
-; moving north
- ld a,[wMapViewVRAMPointer]
- sub a,$40
- ld [wMapViewVRAMPointer],a
- jr nc,.adjustXCoordWithinBlock
- ld a,[wMapViewVRAMPointer + 1]
- dec a
- and a,$03
- or a,$98
- ld [wMapViewVRAMPointer + 1],a
-.adjustXCoordWithinBlock
- ld a,c
- and a
- jr z,.pointlessJump ; mistake?
-.pointlessJump
- ld hl,wXBlockCoord
- ld a,[hl]
- add c
- ld [hl],a
- cp a,$02
- jr nz,.checkForMoveToWestBlock
-; moved into the tile block to the east
- xor a
- ld [hl],a
- ld hl,wXOffsetSinceLastSpecialWarp
- inc [hl]
- ld de,wCurrentTileBlockMapViewPointer
- call MoveTileBlockMapPointerEast
- jr .updateMapView
-.checkForMoveToWestBlock
- cp a,$ff
- jr nz,.adjustYCoordWithinBlock
-; moved into the tile block to the west
- ld a,$01
- ld [hl],a
- ld hl,wXOffsetSinceLastSpecialWarp
- dec [hl]
- ld de,wCurrentTileBlockMapViewPointer
- call MoveTileBlockMapPointerWest
- jr .updateMapView
-.adjustYCoordWithinBlock
- ld hl,wYBlockCoord
- ld a,[hl]
- add b
- ld [hl],a
- cp a,$02
- jr nz,.checkForMoveToNorthBlock
-; moved into the tile block to the south
- xor a
- ld [hl],a
- ld hl,wYOffsetSinceLastSpecialWarp
- inc [hl]
- ld de,wCurrentTileBlockMapViewPointer
- ld a,[wCurMapWidth]
- call MoveTileBlockMapPointerSouth
- jr .updateMapView
-.checkForMoveToNorthBlock
- cp a,$ff
- jr nz,.updateMapView
-; moved into the tile block to the north
- ld a,$01
- ld [hl],a
- ld hl,wYOffsetSinceLastSpecialWarp
- dec [hl]
- ld de,wCurrentTileBlockMapViewPointer
- ld a,[wCurMapWidth]
- call MoveTileBlockMapPointerNorth
-.updateMapView
- call LoadCurrentMapView
- ld a,[wSpriteStateData1 + 3] ; delta Y
- cp a,$01
- jr nz,.checkIfMovingNorth2
-; if moving south
- call ScheduleSouthRowRedraw
- jr .scrollBackgroundAndSprites
-.checkIfMovingNorth2
- cp a,$ff
- jr nz,.checkIfMovingEast2
-; if moving north
- call ScheduleNorthRowRedraw
- jr .scrollBackgroundAndSprites
-.checkIfMovingEast2
- ld a,[wSpriteStateData1 + 5] ; delta X
- cp a,$01
- jr nz,.checkIfMovingWest2
-; if moving east
- call ScheduleEastColumnRedraw
- jr .scrollBackgroundAndSprites
-.checkIfMovingWest2
- cp a,$ff
- jr nz,.scrollBackgroundAndSprites
-; if moving west
- call ScheduleWestColumnRedraw
-.scrollBackgroundAndSprites
- ld a,[wSpriteStateData1 + 3] ; delta Y
- ld b,a
- ld a,[wSpriteStateData1 + 5] ; delta X
- ld c,a
- sla b
- sla c
- ld a,[hSCY]
- add b
- ld [hSCY],a ; update background scroll Y
- ld a,[hSCX]
- add c
- ld [hSCX],a ; update background scroll X
-; shift all the sprites in the direction opposite of the player's motion
-; so that the player appears to move relative to them
- ld hl,wSpriteStateData1 + $14
- ld a,[wNumSprites] ; number of sprites
- and a ; are there any sprites?
- jr z,.done
- ld e,a
-.spriteShiftLoop
- ld a,[hl]
- sub b
- ld [hli],a
- inc l
- ld a,[hl]
- sub c
- ld [hl],a
- ld a,$0e
- add l
- ld l,a
- dec e
- jr nz,.spriteShiftLoop
-.done
- ret
-
-; the following four functions are used to move the pointer to the upper left
-; corner of the tile block map in the direction of motion
-
-MoveTileBlockMapPointerEast::
- ld a,[de]
- add a,$01
- ld [de],a
- ret nc
- inc de
- ld a,[de]
- inc a
- ld [de],a
- ret
-
-MoveTileBlockMapPointerWest::
- ld a,[de]
- sub a,$01
- ld [de],a
- ret nc
- inc de
- ld a,[de]
- dec a
- ld [de],a
- ret
-
-MoveTileBlockMapPointerSouth::
- add a,MAP_BORDER * 2
- ld b,a
- ld a,[de]
- add b
- ld [de],a
- ret nc
- inc de
- ld a,[de]
- inc a
- ld [de],a
- ret
-
-MoveTileBlockMapPointerNorth::
- add a,MAP_BORDER * 2
- ld b,a
- ld a,[de]
- sub b
- ld [de],a
- ret nc
- inc de
- ld a,[de]
- dec a
- ld [de],a
+ ld a, [wUpdateSpritesEnabled]
+ push af
+ ld a, $FF
+ ld [wUpdateSpritesEnabled], a
+ ld hl, _AdvancePlayerSprite ; 3c:410c
+ ld b, BANK(_AdvancePlayerSprite)
+ call Bankswitch
+ pop af
+ ld [wUpdateSpritesEnabled], a
ret
; the following 6 functions are used to tell the V-blank handler to redraw
@@ -1693,197 +1493,216 @@ MoveTileBlockMapPointerNorth::
ScheduleNorthRowRedraw::
coord hl, 0, 0
call CopyToRedrawRowOrColumnSrcTiles
- ld a,[wMapViewVRAMPointer]
- ld [hRedrawRowOrColumnDest],a
- ld a,[wMapViewVRAMPointer + 1]
- ld [hRedrawRowOrColumnDest + 1],a
- ld a,REDRAW_ROW
- ld [hRedrawRowOrColumnMode],a
+ ld a, [wMapViewVRAMPointer]
+ ld [hRedrawRowOrColumnDest], a
+ ld a, [wMapViewVRAMPointer + 1]
+ ld [hRedrawRowOrColumnDest + 1], a
+ ld a, REDRAW_ROW
+ ld [hRedrawRowOrColumnMode], a
ret
CopyToRedrawRowOrColumnSrcTiles::
- ld de,wRedrawRowOrColumnSrcTiles
- ld c,2 * SCREEN_WIDTH
+ ld de, wRedrawRowOrColumnSrcTiles
+ ld c, 2 * SCREEN_WIDTH
.loop
- ld a,[hli]
- ld [de],a
+ ld a, [hli]
+ ld [de], a
inc de
dec c
- jr nz,.loop
+ jr nz, .loop
ret
ScheduleSouthRowRedraw::
coord hl, 0, 16
call CopyToRedrawRowOrColumnSrcTiles
- ld a,[wMapViewVRAMPointer]
- ld l,a
- ld a,[wMapViewVRAMPointer + 1]
- ld h,a
- ld bc,$0200
- add hl,bc
- ld a,h
- and a,$03
- or a,$98
- ld [hRedrawRowOrColumnDest + 1],a
- ld a,l
- ld [hRedrawRowOrColumnDest],a
- ld a,REDRAW_ROW
- ld [hRedrawRowOrColumnMode],a
+ ld a, [wMapViewVRAMPointer]
+ ld l, a
+ ld a, [wMapViewVRAMPointer + 1]
+ ld h, a
+ ld bc, $0200
+ add hl, bc
+ ld a, h
+ and $03
+ or $98
+ ld [hRedrawRowOrColumnDest + 1], a
+ ld a, l
+ ld [hRedrawRowOrColumnDest], a
+ ld a, REDRAW_ROW
+ ld [hRedrawRowOrColumnMode], a
ret
ScheduleEastColumnRedraw::
coord hl, 18, 0
call ScheduleColumnRedrawHelper
- ld a,[wMapViewVRAMPointer]
- ld c,a
- and a,$e0
- ld b,a
- ld a,c
- add a,18
- and a,$1f
+ ld a, [wMapViewVRAMPointer]
+ ld c, a
+ and $e0
+ ld b, a
+ ld a, c
+ add 18
+ and $1f
or b
- ld [hRedrawRowOrColumnDest],a
- ld a,[wMapViewVRAMPointer + 1]
- ld [hRedrawRowOrColumnDest + 1],a
- ld a,REDRAW_COL
- ld [hRedrawRowOrColumnMode],a
+ ld [hRedrawRowOrColumnDest], a
+ ld a, [wMapViewVRAMPointer + 1]
+ ld [hRedrawRowOrColumnDest + 1], a
+ ld a, REDRAW_COL
+ ld [hRedrawRowOrColumnMode], a
ret
ScheduleColumnRedrawHelper::
- ld de,wRedrawRowOrColumnSrcTiles
- ld c,SCREEN_HEIGHT
+ ld de, wRedrawRowOrColumnSrcTiles
+ ld c, SCREEN_HEIGHT
.loop
- ld a,[hli]
- ld [de],a
+ ld a, [hli]
+ ld [de], a
inc de
- ld a,[hl]
- ld [de],a
+ ld a, [hl]
+ ld [de], a
inc de
- ld a,19
+ ld a, 19
add l
- ld l,a
- jr nc,.noCarry
+ ld l, a
+ jr nc, .noCarry
inc h
.noCarry
dec c
- jr nz,.loop
+ jr nz, .loop
ret
ScheduleWestColumnRedraw::
coord hl, 0, 0
call ScheduleColumnRedrawHelper
- ld a,[wMapViewVRAMPointer]
- ld [hRedrawRowOrColumnDest],a
- ld a,[wMapViewVRAMPointer + 1]
- ld [hRedrawRowOrColumnDest + 1],a
- ld a,REDRAW_COL
- ld [hRedrawRowOrColumnMode],a
+ ld a, [wMapViewVRAMPointer]
+ ld [hRedrawRowOrColumnDest], a
+ ld a, [wMapViewVRAMPointer + 1]
+ ld [hRedrawRowOrColumnDest + 1], a
+ ld a, REDRAW_COL
+ ld [hRedrawRowOrColumnMode], a
ret
; function to write the tiles that make up a tile block to memory
; Input: c = tile block ID, hl = destination address
DrawTileBlock::
push hl
- ld a,[wTileSetBlocksPtr] ; pointer to tiles
- ld l,a
- ld a,[wTileSetBlocksPtr + 1]
- ld h,a
- ld a,c
+ ld a, [wTileSetBlocksPtr] ; pointer to tiles
+ ld l, a
+ ld a, [wTileSetBlocksPtr + 1]
+ ld h, a
+ ld a, c
swap a
- ld b,a
- and a,$f0
- ld c,a
- ld a,b
- and a,$0f
- ld b,a ; bc = tile block ID * 0x10
- add hl,bc
- ld d,h
- ld e,l ; de = address of the tile block's tiles
+ ld b, a
+ and $f0
+ ld c, a
+ ld a, b
+ and $0f
+ ld b, a ; bc = tile block ID * 0x10
+ add hl, bc
+ ld d, h
+ ld e, l ; de = address of the tile block's tiles
pop hl
- ld c,$04 ; 4 loop iterations
+ ld c, $04 ; 4 loop iterations
.loop ; each loop iteration, write 4 tile numbers
push bc
- ld a,[de]
- ld [hli],a
+ ld a, [de]
+ ld [hli], a
inc de
- ld a,[de]
- ld [hli],a
+ ld a, [de]
+ ld [hli], a
inc de
- ld a,[de]
- ld [hli],a
+ ld a, [de]
+ ld [hli], a
inc de
- ld a,[de]
- ld [hl],a
+ ld a, [de]
+ ld [hl], a
inc de
- ld bc,$0015
- add hl,bc
+ ld bc, $0015
+ add hl, bc
pop bc
dec c
- jr nz,.loop
+ jr nz, .loop
ret
; function to update joypad state and simulate button presses
JoypadOverworld::
xor a
- ld [wSpriteStateData1 + 3],a
- ld [wSpriteStateData1 + 5],a
+ ld [wSpriteStateData1 + 3], a
+ ld [wSpriteStateData1 + 5], a
call RunMapScript
call Joypad
- ld a,[wFlags_D733]
- bit 3,a ; check if a trainer wants a challenge
- jr nz,.notForcedDownwards
- ld a,[wCurMap]
- cp a,ROUTE_17 ; Cycling Road
- jr nz,.notForcedDownwards
- ld a,[hJoyHeld]
- and a,D_DOWN | D_UP | D_LEFT | D_RIGHT | B_BUTTON | A_BUTTON
- jr nz,.notForcedDownwards
- ld a,D_DOWN
- ld [hJoyHeld],a ; on the cycling road, if there isn't a trainer and the player isn't pressing buttons, simulate a down press
-.notForcedDownwards
- ld a,[wd730]
- bit 7,a
+ call ForceBikeDown
+ call AreInputsSimulated
+ ret
+
+ForceBikeDown::
+ ld a, [wFlags_D733]
+ bit 3, a ; check if a trainer wants a challenge
+ ret nz
+ ld a, [wCurMap]
+ cp ROUTE_17 ; Cycling Road
+ ret nz
+ ld a, [hJoyHeld]
+ and D_DOWN | D_UP | D_LEFT | D_RIGHT | B_BUTTON | A_BUTTON
+ ret nz
+ ld a, D_DOWN
+ ld [hJoyHeld], a ; on the cycling road, if there isn't a trainer and the player isn't pressing buttons, simulate a down press
+ ret
+
+AreInputsSimulated::
+ ld a, [wd730]
+ bit 7, a
ret z
; if simulating button presses
- ld a,[hJoyHeld]
- ld b,a
- ld a,[wOverrideSimulatedJoypadStatesMask] ; bit mask for button presses that override simulated ones
+ ld a, [hJoyHeld]
+ ld b, a
+ ld a, [wOverrideSimulatedJoypadStatesMask] ; bit mask for button presses that override simulated ones
and b
ret nz ; return if the simulated button presses are overridden
- ld hl,wSimulatedJoypadStatesIndex
- dec [hl]
- ld a,[hl]
- cp a,$ff
- jr z,.doneSimulating ; if the end of the simulated button presses has been reached
- ld hl,wSimulatedJoypadStatesEnd
- add l
- ld l,a
- jr nc,.noCarry
- inc h
-.noCarry
- ld a,[hl]
- ld [hJoyHeld],a ; store simulated button press in joypad state
+ call GetSimulatedInput
+ jr nc, .doneSimulating
+ ld [hJoyHeld], a ; store simulated button press in joypad state
and a
ret nz
- ld [hJoyPressed],a
- ld [hJoyReleased],a
+ ld [hJoyPressed], a
+ ld [hJoyReleased], a
ret
+
; if done simulating button presses
.doneSimulating
xor a
- ld [wWastedByteCD3A],a
- ld [wSimulatedJoypadStatesIndex],a
- ld [wSimulatedJoypadStatesEnd],a
- ld [wJoyIgnore],a
- ld [hJoyHeld],a
- ld hl,wd736
- ld a,[hl]
- and a,$f8
- ld [hl],a
- ld hl,wd730
- res 7,[hl]
+ ld [wWastedByteCD3A], a
+ ld [wSimulatedJoypadStatesIndex], a
+ ld [wSimulatedJoypadStatesEnd], a
+ ld [wJoyIgnore], a
+ ld [hJoyHeld], a
+ ld hl, wd736
+ ld a, [hl]
+ and $f8
+ ld [hl], a
+ ld hl, wd730
+ res 7, [hl]
+ ret
+
+GetSimulatedInput::
+ ld hl, wSimulatedJoypadStatesIndex
+ dec [hl]
+ ld a, [hl]
+ cp $ff
+ jr z, .endofsimulatedinputs ; if the end of the simulated button presses has been reached
+ push de
+ ld e, a
+ ld d, $0
+ ld hl, wSimulatedJoypadStatesEnd
+ add hl, de
+ ld a, [hl]
+ pop de
+ scf
ret
+.endofsimulatedinputs
+ and a
+ ret
+
+
; function to check the tile ahead to determine if the character should get on land or keep surfing
; sets carry if there is a collision and clears carry otherwise
; It seems that this function has a bug in it, but due to luck, it doesn't
@@ -1894,62 +1713,54 @@ JoypadOverworld::
; and 2429 always sets c to 0xF0. There is no 0xF0 background tile, so it
; is considered impassable and it is detected as a collision.
CollisionCheckOnWater::
- ld a,[wd730]
- bit 7,a
- jp nz,.noCollision ; return and clear carry if button presses are being simulated
- ld a,[wPlayerDirection] ; the direction that the player is trying to go in
- ld d,a
- ld a,[wSpriteStateData1 + 12] ; the player sprite's collision data (bit field) (set in the sprite movement code)
+ ld a, [wd730]
+ bit 7, a
+ jp nz, .noCollision ; return and clear carry if button presses are being simulated
+ ld a, [wPlayerDirection] ; the direction that the player is trying to go in
+ ld d, a
+ ld a, [wSpriteStateData1 + 12] ; the player sprite's collision data (bit field) (set in the sprite movement code)
and d ; check if a sprite is in the direction the player is trying to go
- jr nz,.checkIfNextTileIsPassable ; bug?
- ld hl,TilePairCollisionsWater
+ jr nz, .collision ; bug?
+ ld hl, TilePairCollisionsWater
call CheckForJumpingAndTilePairCollisions
- jr c,.collision
+ jr c, .collision
predef GetTileAndCoordsInFrontOfPlayer ; get tile in front of player (puts it in c and [wTileInFrontOfPlayer])
- ld a,[wTileInFrontOfPlayer] ; tile in front of player
- cp a,$14 ; water tile
- jr z,.noCollision ; keep surfing if it's a water tile
- cp a,$32 ; either the left tile of the S.S. Anne boarding platform or the tile on eastern coastlines (depending on the current tileset)
- jr z,.checkIfVermilionDockTileset
- cp a,$48 ; tile on right on coast lines in Safari Zone
- jr z,.noCollision ; keep surfing
-; check if the [land] tile in front of the player is passable
-.checkIfNextTileIsPassable
- ld hl,wTileSetCollisionPtr ; pointer to list of passable tiles
- ld a,[hli]
- ld h,[hl]
- ld l,a
-.loop
- ld a,[hli]
- cp a,$ff
- jr z,.collision
- cp c
- jr z,.stopSurfing ; stop surfing if the tile is passable
- jr .loop
+ callab IsNextTileShoreOrWater ; 3:6808
+ jr c, .noCollision
+ ld a, [wTileInFrontOfPlayer] ; tile in front of player
+ ld c, a
+ call IsTilePassable
+ jr nc, .stopSurfing
.collision
- ld a,[wChannelSoundIDs + CH4]
- cp a,SFX_COLLISION ; check if collision sound is already playing
- jr z,.setCarry
- ld a,SFX_COLLISION
+ ld a, [wChannelSoundIDs + CH4]
+ cp $b4 ; SFX_COLLISION
+ jr z, .setCarry
+ ld a, $b4 ; SFX_COLLISION
call PlaySound ; play collision sound (if it's not already playing)
.setCarry
scf
jr .done
-.noCollision
- and a
-.done
- ret
-.stopSurfing
- xor a
- ld [wWalkBikeSurfState],a
- call LoadPlayerSpriteGraphics
- call PlayDefaultMusic
- jr .noCollision
+
.checkIfVermilionDockTileset
ld a, [wCurMapTileset] ; tileset
cp SHIP_PORT ; Vermilion Dock tileset
jr nz, .noCollision ; keep surfing if it's not the boarding platform tile
jr .stopSurfing ; if it is the boarding platform tile, stop surfing
+.stopSurfing ; based game freak
+ ld a, $3
+ ld [wPikachuSpawnState], a
+ ld hl, wPikachuOverworldStateFlags
+ set 5, [hl]
+ xor a
+ ld [wWalkBikeSurfState], a
+ call LoadPlayerSpriteGraphics
+ call PlayDefaultMusic
+ jr .noCollision
+
+.noCollision ; ...and they do the same mistake twice
+ and a
+.done
+ ret
; function to run the current map's script
RunMapScript::
@@ -1957,407 +1768,343 @@ RunMapScript::
push de
push bc
callba TryPushingBoulder
- ld a,[wFlags_0xcd60]
- bit 1,a ; play boulder dust animation
- jr z,.afterBoulderEffect
+ ld a, [wFlags_0xcd60]
+ bit 1, a ; play boulder dust animation
+ jr z, .afterBoulderEffect
callba DoBoulderDustAnimation
.afterBoulderEffect
pop bc
pop de
pop hl
call RunNPCMovementScript
- ld a,[wCurMap] ; current map number
+ ld a, [wCurMap] ; current map number
call SwitchToMapRomBank ; change to the ROM bank the map's data is in
- ld hl,wMapScriptPtr
- ld a,[hli]
- ld h,[hl]
- ld l,a
- ld de,.return
+ ld hl, wMapScriptPtr
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, .return
push de
jp [hl] ; jump to script
.return
ret
LoadWalkingPlayerSpriteGraphics::
- ld de,RedSprite
- ld hl,vNPCSprites
+; new sprite copy stuff
+ xor a
+ ld [wd473], a
+ ld b, BANK(RedSprite)
+ ld de, RedSprite ; $4180
+ jr LoadPlayerSpriteGraphicsCommon
+
+LoadSurfingPlayerSpriteGraphics2::
+ ld a, [wd473]
+ and a
+ jr z, .asm_0d75
+ dec a
+ jr z, LoadSurfingPlayerSpriteGraphics
+ dec a
+ jr z, .asm_0d7c
+.asm_0d75
+ ld a, [wd472]
+ bit 6, a
+ jr z, LoadSurfingPlayerSpriteGraphics
+.asm_0d7c
+ ld b, BANK(SurfingPikachuSprite)
+ ld de, SurfingPikachuSprite ; 3f:6def
jr LoadPlayerSpriteGraphicsCommon
LoadSurfingPlayerSpriteGraphics::
- ld de,SeelSprite
- ld hl,vNPCSprites
+ ld b, BANK(RedSprite) ; not sure, but probably same bank (5)
+ ld de, SeelSprite
jr LoadPlayerSpriteGraphicsCommon
LoadBikePlayerSpriteGraphics::
- ld de,RedCyclingSprite
- ld hl,vNPCSprites
-
+ ld b, BANK(RedCyclingSprite)
+ ld de, RedCyclingSprite
LoadPlayerSpriteGraphicsCommon::
+ ld hl, vNPCSprites
push de
push hl
- lb bc, BANK(RedSprite), $0c
+ push bc
+ ld c, $c
call CopyVideoData
+ pop bc
pop hl
pop de
- ld a,$c0
+ ld a, $c0
add e
- ld e,a
- jr nc,.noCarry
+ ld e, a
+ jr nc, .noCarry
inc d
.noCarry
- set 3,h
- lb bc, BANK(RedSprite), $0c
+ set 3, h
+ ld c, $c
jp CopyVideoData
; function to load data from the map header
LoadMapHeader::
callba MarkTownVisitedAndLoadMissableObjects
- ld a,[wCurMapTileset]
- ld [wUnusedD119],a
- ld a,[wCurMap]
+ jr asm_0dbd
+
+Func_0db5:: ; XXX
+ callba LoadUnusedBluesHouseMissableObjectData ; 3c:4a55
+asm_0dbd
+ ld a, [wCurMapTileset]
+ ld [wUnusedD119], a
+ ld a, [wCurMap]
call SwitchToMapRomBank
- ld a,[wCurMapTileset]
- ld b,a
- res 7,a
- ld [wCurMapTileset],a
- ld [hPreviousTileset],a
- bit 7,b
+ ld a, [wCurMapTileset]
+ ld b, a
+ res 7, a
+ ld [wCurMapTileset], a
+ ld [hPreviousTileset], a
+ bit 7, b
ret nz
- ld hl,MapHeaderPointers
- ld a,[wCurMap]
- sla a
- jr nc,.noCarry1
- inc h
-.noCarry1
- add l
- ld l,a
- jr nc,.noCarry2
- inc h
-.noCarry2
- ld a,[hli]
- ld h,[hl]
- ld l,a ; hl = base of map header
+ call GetMapHeaderPointer
; copy the first 10 bytes (the fixed area) of the map data to D367-D370
- ld de,wCurMapTileset
- ld c,$0a
+ ld de, wCurMapTileset
+ ld c, $0a
.copyFixedHeaderLoop
- ld a,[hli]
- ld [de],a
+ ld a, [hli]
+ ld [de], a
inc de
dec c
- jr nz,.copyFixedHeaderLoop
+ jr nz, .copyFixedHeaderLoop
; initialize all the connected maps to disabled at first, before loading the actual values
- ld a,$ff
- ld [wMapConn1Ptr],a
- ld [wMapConn2Ptr],a
- ld [wMapConn3Ptr],a
- ld [wMapConn4Ptr],a
+ ld a, $ff
+ ld [wMapConn1Ptr], a
+ ld [wMapConn2Ptr], a
+ ld [wMapConn3Ptr], a
+ ld [wMapConn4Ptr], a
; copy connection data (if any) to WRAM
- ld a,[wMapConnections]
- ld b,a
+ ld a, [wMapConnections]
+ ld b, a
.checkNorth
- bit 3,b
- jr z,.checkSouth
- ld de,wMapConn1Ptr
+ bit 3, b
+ jr z, .checkSouth
+ ld de, wMapConn1Ptr
call CopyMapConnectionHeader
.checkSouth
- bit 2,b
- jr z,.checkWest
- ld de,wMapConn2Ptr
+ bit 2, b
+ jr z, .checkWest
+ ld de, wMapConn2Ptr
call CopyMapConnectionHeader
.checkWest
- bit 1,b
- jr z,.checkEast
- ld de,wMapConn3Ptr
+ bit 1, b
+ jr z, .checkEast
+ ld de, wMapConn3Ptr
call CopyMapConnectionHeader
.checkEast
- bit 0,b
- jr z,.getObjectDataPointer
- ld de,wMapConn4Ptr
+ bit 0, b
+ jr z, .getObjectDataPointer
+ ld de, wMapConn4Ptr
call CopyMapConnectionHeader
.getObjectDataPointer
- ld a,[hli]
- ld [wObjectDataPointerTemp],a
- ld a,[hli]
- ld [wObjectDataPointerTemp + 1],a
+ ld a, [hli]
+ ld [wObjectDataPointerTemp], a
+ ld a, [hli]
+ ld [wObjectDataPointerTemp + 1], a
push hl
- ld a,[wObjectDataPointerTemp]
- ld l,a
- ld a,[wObjectDataPointerTemp + 1]
- ld h,a ; hl = base of object data
- ld de,wMapBackgroundTile
- ld a,[hli]
- ld [de],a
+ ld a, [wObjectDataPointerTemp]
+ ld l, a
+ ld a, [wObjectDataPointerTemp + 1]
+ ld h, a ; hl = base of object data
+ ld de, wMapBackgroundTile
+ ld a, [hli]
+ ld [de], a
.loadWarpData
- ld a,[hli]
- ld [wNumberOfWarps],a
+ ld a, [hli]
+ ld [wNumberOfWarps], a
and a
- jr z,.loadSignData
- ld c,a
- ld de,wWarpEntries
+ jr z, .loadSignData
+ ld c, a
+ ld de, wWarpEntries
.warpLoop ; one warp per loop iteration
- ld b,$04
+ ld b, $04
.warpInnerLoop
- ld a,[hli]
- ld [de],a
+ ld a, [hli]
+ ld [de], a
inc de
dec b
- jr nz,.warpInnerLoop
+ jr nz, .warpInnerLoop
dec c
- jr nz,.warpLoop
+ jr nz, .warpLoop
.loadSignData
- ld a,[hli] ; number of signs
- ld [wNumSigns],a
+ ld a, [hli] ; number of signs
+ ld [wNumSigns], a
and a ; are there any signs?
- jr z,.loadSpriteData ; if not, skip this
- ld c,a
- ld de,wSignTextIDs
- ld a,d
- ld [hSignCoordPointer],a
- ld a,e
- ld [hSignCoordPointer + 1],a
- ld de,wSignCoords
-.signLoop
- ld a,[hli]
- ld [de],a
- inc de
- ld a,[hli]
- ld [de],a
- inc de
- push de
- ld a,[hSignCoordPointer]
- ld d,a
- ld a,[hSignCoordPointer + 1]
- ld e,a
- ld a,[hli]
- ld [de],a
- inc de
- ld a,d
- ld [hSignCoordPointer],a
- ld a,e
- ld [hSignCoordPointer + 1],a
- pop de
- dec c
- jr nz,.signLoop
+ jr z, .loadSpriteData ; if not, skip this
+ call CopySignData ; 0eb3 (0:0eb3)
.loadSpriteData
- ld a,[wd72e]
- bit 5,a ; did a battle happen immediately before this?
- jp nz,.finishUp ; if so, skip this because battles don't destroy this data
- ld a,[hli]
- ld [wNumSprites],a ; save the number of sprites
- push hl
-; zero C110-C1FF and C210-C2FF
- ld hl,wSpriteStateData1 + $10
- ld de,wSpriteStateData2 + $10
- xor a
- ld b,$f0
-.zeroSpriteDataLoop
- ld [hli],a
- ld [de],a
- inc e
- dec b
- jr nz,.zeroSpriteDataLoop
-; initialize all C100-C1FF sprite entries to disabled (other than player's)
- ld hl,wSpriteStateData1 + $12
- ld de,$0010
- ld c,$0f
-.disableSpriteEntriesLoop
- ld [hl],$ff
- add hl,de
- dec c
- jr nz,.disableSpriteEntriesLoop
- pop hl
- ld de,wSpriteStateData1 + $10
- ld a,[wNumSprites] ; number of sprites
- and a ; are there any sprites?
- jp z,.finishUp ; if there are no sprites, skip the rest
- ld b,a
- ld c,$00
-.loadSpriteLoop
- ld a,[hli]
- ld [de],a ; store picture ID at C1X0
- inc d
- ld a,$04
- add e
- ld e,a
- ld a,[hli]
- ld [de],a ; store Y position at C2X4
- inc e
- ld a,[hli]
- ld [de],a ; store X position at C2X5
- inc e
- ld a,[hli]
- ld [de],a ; store movement byte 1 at C2X6
- ld a,[hli]
- ld [hLoadSpriteTemp1],a ; save movement byte 2
- ld a,[hli]
- ld [hLoadSpriteTemp2],a ; save text ID and flags byte
- push bc
- push hl
- ld b,$00
- ld hl,wMapSpriteData
- add hl,bc
- ld a,[hLoadSpriteTemp1]
- ld [hli],a ; store movement byte 2 in byte 0 of sprite entry
- ld a,[hLoadSpriteTemp2]
- ld [hl],a ; this appears pointless, since the value is overwritten immediately after
- ld a,[hLoadSpriteTemp2]
- ld [hLoadSpriteTemp1],a
- and a,$3f
- ld [hl],a ; store text ID in byte 1 of sprite entry
- pop hl
- ld a,[hLoadSpriteTemp1]
- bit 6,a
- jr nz,.trainerSprite
- bit 7,a
- jr nz,.itemBallSprite
- jr .regularSprite
-.trainerSprite
- ld a,[hli]
- ld [hLoadSpriteTemp1],a ; save trainer class
- ld a,[hli]
- ld [hLoadSpriteTemp2],a ; save trainer number (within class)
- push hl
- ld hl,wMapSpriteExtraData
- add hl,bc
- ld a,[hLoadSpriteTemp1]
- ld [hli],a ; store trainer class in byte 0 of the entry
- ld a,[hLoadSpriteTemp2]
- ld [hl],a ; store trainer number in byte 1 of the entry
- pop hl
- jr .nextSprite
-.itemBallSprite
- ld a,[hli]
- ld [hLoadSpriteTemp1],a ; save item number
- push hl
- ld hl,wMapSpriteExtraData
- add hl,bc
- ld a,[hLoadSpriteTemp1]
- ld [hli],a ; store item number in byte 0 of the entry
- xor a
- ld [hl],a ; zero byte 1, since it is not used
- pop hl
- jr .nextSprite
-.regularSprite
- push hl
- ld hl,wMapSpriteExtraData
- add hl,bc
-; zero both bytes, since regular sprites don't use this extra space
- xor a
- ld [hli],a
- ld [hl],a
- pop hl
-.nextSprite
- pop bc
- dec d
- ld a,$0a
- add e
- ld e,a
- inc c
- inc c
- dec b
- jp nz,.loadSpriteLoop
+ ld a, [wd72e]
+ bit 5, a ; did a battle happen immediately before this?
+ jr nz, .finishUp ; if so, skip this because battles don't destroy this data
+ call InitSprites
.finishUp
predef LoadTilesetHeader
- callab LoadWildData
+ ld a, [wd72e]
+ bit 5, a ; did a battle happen immediately before this?
+ jr nz, .skip_pika_spawn
+ callab SchedulePikachuSpawnForAfterText ; 3f:44fa
+.skip_pika_spawn
+ callab LoadWildData ; 3:4b62
pop hl ; restore hl from before going to the warp/sign/sprite data (this value was saved for seemingly no purpose)
- ld a,[wCurMapHeight] ; map height in 4x4 tile blocks
+ ld a, [wCurMapHeight] ; map height in 4x4 tile blocks
add a ; double it
- ld [wCurrentMapHeight2],a ; store map height in 2x2 tile blocks
- ld a,[wCurMapWidth] ; map width in 4x4 tile blocks
+ ld [wCurrentMapHeight2], a ; store map height in 2x2 tile blocks
+ ld a, [wCurMapWidth] ; map width in 4x4 tile blocks
add a ; double it
- ld [wCurrentMapWidth2],a ; map width in 2x2 tile blocks
- ld a,[wCurMap]
- ld c,a
- ld b,$00
- ld a,[H_LOADEDROMBANK]
+ ld [wCurrentMapWidth2], a ; map width in 2x2 tile blocks
+ ld a, [wCurMap]
+ ld c, a
+ ld b, $00
+ ld a, [H_LOADEDROMBANK]
push af
- ld a, BANK(MapSongBanks)
- ld [H_LOADEDROMBANK],a
- ld [MBC1RomBank],a
- ld hl, MapSongBanks
- add hl,bc
- add hl,bc
- ld a,[hli]
- ld [wMapMusicSoundID],a ; music 1
- ld a,[hl]
- ld [wMapMusicROMBank],a ; music 2
+ switchbank MapSongBanks
+ ld hl, MapSongBanks ; 3f:4000
+ add hl, bc
+ add hl, bc
+ ld a, [hli]
+ ld [wMapMusicSoundID], a ; music 1
+ ld a, [hl]
+ ld [wMapMusicROMBank], a ; music 2
pop af
- ld [H_LOADEDROMBANK],a
- ld [MBC1RomBank],a
+ call BankswitchCommon
ret
; function to copy map connection data from ROM to WRAM
; Input: hl = source, de = destination
CopyMapConnectionHeader::
- ld c,$0b
+ ld c, $0b
.loop
- ld a,[hli]
- ld [de],a
+ ld a, [hli]
+ ld [de], a
inc de
dec c
- jr nz,.loop
+ jr nz, .loop
+ ret
+
+CopySignData::
+ ld de, wSignCoords ; start of sign coords
+ ld bc, wSignTextIDs ; start of sign text ids
+ ld a, [wNumSigns] ; number of signs
+.signcopyloop
+ push af
+ ld a, [hli]
+ ld [de], a ; copy y coord
+ inc de
+ ld a, [hli]
+ ld [de], a ; copy x coord
+ inc de
+ ld a, [hli]
+ ld [bc], a ; copy sign text id
+ inc bc
+ pop af
+ dec a
+ jr nz, .signcopyloop
ret
; function to load map data
LoadMapData::
- ld a,[H_LOADEDROMBANK]
+ ld a, [H_LOADEDROMBANK]
push af
call DisableLCD
- ld a,$98
- ld [wMapViewVRAMPointer + 1],a
- xor a
- ld [wMapViewVRAMPointer],a
- ld [hSCY],a
- ld [hSCX],a
- ld [wWalkCounter],a
- ld [wUnusedD119],a
- ld [wWalkBikeSurfStateCopy],a
- ld [wSpriteSetID],a
+ call ResetMapVariables
call LoadTextBoxTilePatterns
call LoadMapHeader
- callba InitMapSprites ; load tile pattern data for sprites
+ call InitMapSprites ; load tile pattern data for sprites
+ call LoadScreenRelatedData
+ call CopyMapViewToVRAM
+ ld a, $01
+ ld [wUpdateSpritesEnabled], a
+ call EnableLCD
+ ld b, $09
+ call RunPaletteCommand
+ call LoadPlayerSpriteGraphics
+ ld a, [wd732]
+ and 1 << 4 | 1 << 3 ; fly warp or dungeon warp
+ jr nz, .restoreRomBank
+ ld a, [wFlags_D733]
+ bit 1, a
+ jr nz, .restoreRomBank
+ call UpdateMusic6Times ; music related
+ call PlayDefaultMusicFadeOutCurrent ; music related
+.restoreRomBank
+ pop af
+ call BankswitchCommon
+ ret
+
+LoadScreenRelatedData::
call LoadTileBlockMap
call LoadTilesetTilePatternData
call LoadCurrentMapView
+ ret
+
+ReloadMapAfterSurfingMinigame::
+ ld a, [H_LOADEDROMBANK]
+ push af
+ call DisableLCD
+ call ResetMapVariables
+ ld a, [wCurMap]
+ call SwitchToMapRomBank
+ call LoadScreenRelatedData
+ call CopyMapViewToVRAM
+ ld de, vBGMap1
+ call CopyMapViewToVRAM2
+ call EnableLCD
+ call ReloadMapSpriteTilePatterns
+ pop af
+ call BankswitchCommon
+ jr asm_0f4d
+
+ReloadMapAfterPrinter::
+ ld a, [H_LOADEDROMBANK]
+ push af
+ ld a, [wCurMap]
+ call SwitchToMapRomBank
+ call LoadTileBlockMap
+ pop af
+ call BankswitchCommon
+asm_0f4d:
+ jpab SetMapSpecificScriptFlagsOnMapReload
+ ret ; useless?
+
+ResetMapVariables::
+ ld a, $98
+ ld [wMapViewVRAMPointer + 1], a
+ xor a
+ ld [wMapViewVRAMPointer], a
+ ld [hSCY], a
+ ld [hSCX], a
+ ld [wWalkCounter], a
+ ld [wUnusedD119], a
+ ld [wSpriteSetID], a
+ ld [wWalkBikeSurfStateCopy], a
+ ret
+
+CopyMapViewToVRAM::
; copy current map view to VRAM
- coord hl, 0, 0
- ld de,vBGMap0
- ld b,18
+ ld de, vBGMap0
+CopyMapViewToVRAM2:
+ ld hl, wTileMap
+ ld b, 18
.vramCopyLoop
- ld c,20
+ ld c, 20
.vramCopyInnerLoop
- ld a,[hli]
- ld [de],a
+ ld a, [hli]
+ ld [de], a
inc e
dec c
- jr nz,.vramCopyInnerLoop
- ld a,32 - 20
+ jr nz, .vramCopyInnerLoop
+ ld a, 32 - 20 ; total vram map width in tiles - screen width in tiles
add e
- ld e,a
- jr nc,.noCarry
+ ld e, a
+ jr nc, .noCarry
inc d
.noCarry
dec b
- jr nz,.vramCopyLoop
- ld a,$01
- ld [wUpdateSpritesEnabled],a
- call EnableLCD
- ld b, SET_PAL_OVERWORLD
- call RunPaletteCommand
- call LoadPlayerSpriteGraphics
- ld a,[wd732]
- and a,1 << 4 | 1 << 3 ; fly warp or dungeon warp
- jr nz,.restoreRomBank
- ld a,[wFlags_D733]
- bit 1,a
- jr nz,.restoreRomBank
- call UpdateMusic6Times
- call PlayDefaultMusicFadeOutCurrent
-.restoreRomBank
- pop af
- ld [H_LOADEDROMBANK],a
- ld [MBC1RomBank],a
+ jr nz, .vramCopyLoop
ret
; function to switch to the ROM bank that a map is stored in
@@ -2365,28 +2112,45 @@ LoadMapData::
SwitchToMapRomBank::
push hl
push bc
- ld c,a
- ld b,$00
- ld a,Bank(MapHeaderBanks)
- call BankswitchHome ; switch to ROM bank 3
- ld hl,MapHeaderBanks
- add hl,bc
- ld a,[hl]
- ld [$ffe8],a ; save map ROM bank
+ ld c, a
+ ld b, $00
+ ld a, BANK(MapHeaderBanks)
+ call BankswitchHome ; switch to ROM bank 3F
+ ld hl, MapHeaderBanks
+ add hl, bc
+ ld a, [hl]
+ ld [$ffe8], a ; save map ROM bank
call BankswitchBack
- ld a,[$ffe8]
- ld [H_LOADEDROMBANK],a
- ld [MBC1RomBank],a ; switch to map ROM bank
+ ld a, [$ffe8]
+ call BankswitchCommon
pop bc
pop hl
ret
+GetMapHeaderPointer::
+ ld a, [H_LOADEDROMBANK]
+ push af
+ switchbank MapHeaderPointers ; 3f:41f2
+ push de
+ ld a, [wCurMap]
+ ld e, a
+ ld d, $0
+ ld hl, MapHeaderPointers
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ pop de
+ pop af
+ jp BankswitchCommon
+
IgnoreInputForHalfSecond:
ld a, 30
ld [wIgnoreInputCounter], a
ld hl, wd730
ld a, [hl]
- or $26
+ or %00100110 ; $26
ld [hl], a ; set ignore input bit
ret
@@ -2400,3 +2164,160 @@ ForceBikeOrSurf::
ld hl, LoadPlayerSpriteGraphics
call Bankswitch
jp PlayDefaultMusic ; update map/player state?
+
+; Handle the player jumping down
+; a ledge in the overworld.
+HandleMidJump::
+ ld a, [wd736]
+ bit 6, a ; jumping down a ledge?
+ ret z
+ callba _HandleMidJump
+ ret
+
+IsSpinning::
+ ld a, [wd736]
+ bit 7, a
+ ret z ; no spinning
+ jpba LoadSpinnerArrowTiles ; spin while moving
+
+Func_0ffe::
+ jpab IsPlayerTalkingToPikachu
+
+InitSprites::
+ ld a, [hli]
+ ld [wNumSprites], a ; save the number of sprites
+ push hl
+ push de
+ push bc
+ call ZeroSpriteStateData
+ call DisableRegularSprites
+ ld hl, wMapSpriteData
+ ld bc, $20
+ xor a
+ call FillMemory
+ pop bc
+ pop de
+ pop hl
+ ld a, [wNumSprites]
+ and a ; are sprites existant?
+ ret z ; don't copy sprite data if not
+ ld b, a
+ ld c, $0
+ ld de, wSpriteStateData1 + $10
+; copy sprite stuff?
+.loadSpriteLoop
+ ld a, [hli]
+ ld [de], a ; store picture ID at C1X0
+ inc d
+ ld a, e
+ add $4
+ ld e, a
+ ld a, [hli]
+ ld [de], a ; store Y position at C2X4
+ inc e
+ ld a, [hli]
+ ld [de], a ; store X position at C2X5
+ inc e
+ ld a, [hli]
+ ld [de], a ; store movement byte 1 at C2X6
+ ld a, [hli]
+ ld [$ff8d], a ; save movement byte 2
+ ld a, [hli]
+ ld [$ff8e], a ; save text ID and flags byte
+ push bc
+ call LoadSprite
+ pop bc
+ dec d
+ ld a, e
+ add $a
+ ld e, a
+ inc c
+ inc c
+ dec b
+ jr nz, .loadSpriteLoop
+ ret
+
+ZeroSpriteStateData::
+; zero C110-C1EF and C210-C2EF
+; C1F0-C1FF and C2F0-C2FF is used for Pikachu
+ ld hl, wSpriteStateData1 + $10
+ ld de, wSpriteStateData2 + $10
+ xor a
+ ld b, 14 * $10
+.loop
+ ld [hli], a
+ ld [de], a
+ inc e
+ dec b
+ jr nz, .loop
+ ret
+
+DisableRegularSprites::
+; initialize all C100-C1FF sprite entries to disabled (other than player's and pikachu)
+ ld hl, wSpriteStateData1 + 1 * $10 + 2
+ ld de, $10
+ ld c, $e
+.loop
+ ld [hl], $ff
+ add hl, de
+ dec c
+ jr nz, .loop
+ ret
+
+LoadSprite::
+ push hl
+ ld b, $0
+ ld hl, wMapSpriteData
+ add hl, bc
+ ld a, [$ff8d]
+ ld [hli], a ; store movement byte 2 in byte 0 of sprite entry
+ ld a, [$ff8e]
+ ld [hl], a ; this appears pointless, since the value is overwritten immediately after
+ ld a, [$ff8e]
+ ld [$ff8d], a
+ and $3f
+ ld [hl], a ; store text ID in byte 1 of sprite entry
+ pop hl
+ ld a, [$ff8d]
+ bit 6, a
+ jr nz, .trainerSprite
+ bit 7, a
+ jr nz, .itemBallSprite
+; for regular sprites
+ push hl
+ ld hl, wMapSpriteExtraData
+ add hl, bc
+; zero both bytes, since regular sprites don't use this extra space
+ xor a
+ ld [hli], a
+ ld [hl], a
+ pop hl
+ ret
+
+.trainerSprite
+ ld a, [hli]
+ ld [$ff8d], a ; save trainer class
+ ld a, [hli]
+ ld [$ff8e], a ; save trainer number (within class)
+ push hl
+ ld hl, wMapSpriteExtraData
+ add hl, bc
+ ld a, [$ff8d]
+ ld [hli], a ; store trainer class in byte 0 of the entry
+ ld a, [$ff8e]
+ ld [hl], a ; store trainer number in byte 1 of the entry
+ pop hl
+ ret
+
+.itemBallSprite
+ ld a, [hli]
+ ld [$ff8d], a ; save item number
+ push hl
+ ld hl, wMapSpriteExtraData
+ add hl, bc
+ ld a, [$ff8d]
+ ld [hli], a ; store item number in byte 0 of the entry
+ xor a
+ ld [hl], a ; zero byte 1, since it is not used
+ pop hl
+ ret ; end of home/overworld.asm = 10b9 (0:10b9)