summaryrefslogtreecommitdiff
path: root/home/overworld.asm
diff options
context:
space:
mode:
Diffstat (limited to 'home/overworld.asm')
-rw-r--r--home/overworld.asm1428
1 files changed, 657 insertions, 771 deletions
diff --git a/home/overworld.asm b/home/overworld.asm
index 051d055e..7b9fadfa 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::
+EnterMap:: ; 01d7 (0:01d7)
; 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
@@ -38,19 +40,18 @@ EnterMap::
xor a
ld [wJoyIgnore], a
-OverworldLoop::
+OverworldLoop:: ; 0242 (0:0242)
call DelayFrame
-OverworldLoopLessDelay::
+OverworldLoopLessDelay:: ; 0245 (0:0245)
call DelayFrame
+ call IsSurfingPikachuInParty
call LoadGBPal
- ld a,[wd736]
- bit 6,a ; jumping down a ledge?
- call nz, HandleMidJump
+ call HandleMidJump
ld a,[wWalkCounter]
and a
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
+ callba SafariZoneCheck ; 7:6321
ld a,[wSafariZoneGameOver]
and a
jp nz,WarpFound2
@@ -91,7 +92,10 @@ OverworldLoopLessDelay::
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
+ xor a
+ ld [wd436],a ; new yellow address
call IsSpriteOrSignInFrontOfPlayer
+ call Func_0ffe
ld a,[hSpriteIndexOrTextID]
and a
jp z,OverworldLoop
@@ -109,39 +113,38 @@ OverworldLoopLessDelay::
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,[W_CURMAP]
- ld [wDestinationMap],a
- call SpecialWarpIn
- ld a,[W_CURMAP]
- call SwitchToMapRomBank ; switch to the ROM bank of the current map
- ld hl,W_CURMAPTILESET
- set 7,[hl]
-.changeMap
+ xor a
+ ld [wcc47],a
jp EnterMap
+; predef LoadSAV
+; ld a,[W_CURMAP]
+; ld [wDestinationMap],a
+; call SpecialWarpIn
+; ld a,[W_CURMAP]
+; call SwitchToMapRomBank ; switch to the ROM bank of the current map
+; ld hl,W_CURMAPTILESET
+; set 7,[hl]
.checkForOpponent
ld a,[W_CUROPPONENT]
and a
jp nz,.newBattle
jp OverworldLoop
.noDirectionButtonsPressed
+ call UpdateSprites ; 231c
ld hl,wFlags_0xcd60
res 2,[hl]
- call UpdateSprites
- ld a,1
+ 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
xor a
ld [wPlayerMovingDirection],a ; zero the direction
+.overworldloop
jp OverworldLoop
.checkIfDownButtonIsPressed
ld a,[hJoyHeld] ; current joypad state
@@ -168,8 +171,9 @@ OverworldLoopLessDelay::
.checkIfRightButtonIsPressed
bit 4,a ; right button
jr z,.noDirectionButtonsPressed
- ld a,1 ; PLAYER_DIR_RIGHT
- ld [wSpriteStateData1 + 5],a ; delta X
+ ld a,$1
+ ld [wSpriteStateData1 + 5],a
+ ld a,$1
.handleDirectionButtonPress
ld [wPlayerDirection],a ; new direction
ld a,[wd730]
@@ -183,46 +187,15 @@ OverworldLoopLessDelay::
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 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]
- ld hl,wCheckFor180DegreeTurn
- dec [hl]
- jr nz,.holdIntermediateDirectionLoop
- ld a,[wPlayerDirection]
- ld [wPlayerMovingDirection],a
+ xor a
+ ld [wCheckFor180DegreeTurn],a
+ ld a,[wd52a]
+ ld [wd528],a
call NewBattle
jp c,.battleOccurred
jp OverworldLoop
@@ -254,46 +227,25 @@ OverworldLoopLessDelay::
.noCollision
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
+ xor a
+ ld [wd435],a
+ call DoBikeSpeedup
call AdvancePlayerSprite
ld a,[wWalkCounter]
and a
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
+ call StepCountCheck
+ ld a,[wd790]
+ bit 7,a ; in the safari zone?
jr z,.notSafariZone
callba SafariZoneCheckSteps
ld a,[wSafariZoneGameOver]
@@ -325,7 +277,8 @@ OverworldLoopLessDelay::
ld a,[W_CURMAP]
cp a,CINNABAR_GYM
jr nz,.notCinnabarGym
- SetEvent EVENT_2A7
+ ld hl,wd79b
+ set 7,[hl]
.notCinnabarGym
ld hl,wd72e
set 5,[hl]
@@ -335,12 +288,31 @@ OverworldLoopLessDelay::
callab AnyPartyAlive
ld a,d
and a
- jr z,.allPokemonFainted
+ jr z,AllPokemonFainted
.noFaintCheck
ld c,10
call DelayFrames
jp EnterMap
-.allPokemonFainted
+
+StepCountCheck:: ; 0457 (0:0457)
+ 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:: ; 0475 (0:0475)
ld a,$ff
ld [W_ISINBATTLE],a
call RunMapScript
@@ -348,7 +320,7 @@ OverworldLoopLessDelay::
; 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:: ; 0683 (0:0683)
+NewBattle:: ; 0480 (0:0480)
ld a,[wd72d]
bit 4,a
jr nz,.noBattle
@@ -357,39 +329,45 @@ NewBattle:: ; 0683 (0:0683)
ld a,[wd72e]
bit 4,a
jr nz,.noBattle
- jpba InitBattle
+ jpba InitBattle ; 3d:5ff2
.noBattle
and a
ret
-; function to make bikes twice as fast as walking
-BikeSpeedup:: ; 06a0 (0:06a0)
+DoBikeSpeedup:: ; 049d (0:049d)
+ 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,[W_CURMAP]
- cp a,ROUTE_17 ; Cycling Road
+ cp ROUTE_17 ; cycling road
jr nz,.goFaster
ld a,[hJoyHeld]
and a,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:: ; 06b4 (0:06b4)
+CheckWarpsNoCollision:: ; 04bd (0:04bd)
ld a,[wNumberOfWarps]
and a
jp z,CheckMapConnections
- ld a,[wNumberOfWarps]
ld b,0
+ ld a,[wNumberOfWarps]
ld c,a
ld a,[W_YCOORD]
ld d,a
ld a,[W_XCOORD]
ld e,a
ld hl,wWarpEntries
-CheckWarpsNoCollisionLoop:: ; 06cc (0:06cc)
+CheckWarpsNoCollisionLoop:: ; 04d5 (0:04d5)
ld a,[hli] ; check if the warp's Y position matches
cp d
jr nz,CheckWarpsNoCollisionRetry1
@@ -424,9 +402,20 @@ CheckWarpsNoCollisionLoop:: ; 06cc (0:06cc)
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
jr WarpFound1
-
+
+CheckWarpsNoCollisionRetry1:: ; 050f (0:050f)
+ inc hl
+CheckWarpsNoCollisionRetry2:: ; 0510 (0:0510)
+ inc hl
+ inc hl
+ContinueCheckWarpsNoCollisionLoop:: ; 0512 (0:0512)
+ 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:: ; 0706 (0:0706)
+CheckWarpsCollision:: ; 051a (0:051a)
ld a,[wNumberOfWarps]
ld c,a
ld hl,wWarpEntries
@@ -455,20 +444,13 @@ CheckWarpsCollision:: ; 0706 (0:0706)
jr nz,.loop
jp OverworldLoop
-CheckWarpsNoCollisionRetry1:: ; 072f (0:072f)
- inc hl
-CheckWarpsNoCollisionRetry2:: ; 0730 (0:0730)
- inc hl
- inc hl
- jp ContinueCheckWarpsNoCollisionLoop
-
-WarpFound1:: ; 0735 (0:0735)
+WarpFound1:: ; 0543 (0:0543)
ld a,[hli]
ld [wDestinationWarpID],a
ld a,[hli]
ld [hWarpDestinationMap],a
-WarpFound2:: ; 073c (0:073c)
+WarpFound2:: ; 054a (0:054a)
ld a,[wNumberOfWarps]
sub c
ld [wWarpedFromWhichWarp],a ; save ID of used warp
@@ -489,6 +471,7 @@ WarpFound2:: ; 073c (0:073c)
ld [wMapPalOffset],a
call GBFadeOutToBlack
.notRockTunnel
+ callab Func_fc5fa ; 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
@@ -503,9 +486,9 @@ WarpFound2:: ; 073c (0:073c)
dec a ; is the player on a warp pad?
jr nz,.notWarpPad
; if the player is on a warp pad
+ call LeaveMapAnim
ld hl,wd732
set 3,[hl]
- call LeaveMapAnim
jr .skipMapChangeSound
.notWarpPad
call PlayMapChangeSound
@@ -513,8 +496,10 @@ WarpFound2:: ; 073c (0:073c)
ld hl,wd736
res 0,[hl]
res 1,[hl]
+ callab Func_fc65b ; 3f:465b
jr .done
.goBackOutside
+ callab Func_fc69a ; 3f:469a
ld a,[wLastMap]
ld [W_CURMAP],a
call PlayMapChangeSound
@@ -526,13 +511,8 @@ WarpFound2:: ; 073c (0:073c)
call IgnoreInputForHalfSecond
jp EnterMap
-ContinueCheckWarpsNoCollisionLoop:: ; 07b5 (0:07b5)
- inc b ; increment warp number
- dec c ; decrement number of warps
- jp nz,CheckWarpsNoCollisionLoop
-
; if no matching warp was found
-CheckMapConnections:: ; 07ba (0:07ba)
+CheckMapConnections:: ; 05db (0:05db)
.checkWestMap
ld a,[W_XCOORD]
cp a,$ff
@@ -656,28 +636,38 @@ CheckMapConnections:: ; 07ba (0:07ba)
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
- ld b, SET_PAL_OVERWORLD
+.loadNewMap ; 06ce (0:06ce)
+; load the connected map that was entered
+ ld hl,wd430
+ set 4,[hl]
+ ld a,$2
+ ld [wd431],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:: ; 08c9 (0:08c9)
+PlayMapChangeSound:: ; 06ef (0:06ef)
+ ld a,[W_CURMAPTILESET]
+ 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
+ cp UNDERGROUND ; door tile in tileset 0
jr nz,.didNotGoThroughDoor
- ld a,SFX_GO_INSIDE
+ 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]
@@ -685,7 +675,7 @@ PlayMapChangeSound:: ; 08c9 (0:08c9)
ret nz
jp GBFadeOutToBlack
-CheckIfInOutsideMap:: ; 08e1 (0:08e1)
+CheckIfInOutsideMap:: ; 0712 (0:0712)
; If the player is in an outside map (a town or route), set the z flag
ld a, [W_CURMAPTILESET]
and a ; most towns/routes have tileset 0 (OVERWORLD)
@@ -699,7 +689,7 @@ CheckIfInOutsideMap:: ; 08e1 (0:08e1)
; "function 1" passes when the player is at the edge of the map and is facing towards the outside of the map
; "function 2" passes when the the tile in front of the player is among a certain set
; sets carry if the check passes, otherwise clears carry
-ExtraWarpCheck:: ; 08e9 (0:08e9)
+ExtraWarpCheck:: ; 071a (0:071a)
ld a, [W_CURMAP]
cp SS_ANNE_3
jr z, .useFunction1
@@ -729,14 +719,14 @@ ExtraWarpCheck:: ; 08e9 (0:08e9)
ld b, BANK(IsWarpTileInFrontOfPlayer)
jp Bankswitch
-MapEntryAfterBattle:: ; 091f (0:091f)
+MapEntryAfterBattle:: ; 0750 (0:0750)
callba IsPlayerStandingOnWarp ; for enabling warp testing after collisions
ld a,[wMapPalOffset]
and a
jp z,GBFadeInFromWhite
jp LoadGBPal
-HandleBlackOut::
+HandleBlackOut:: ; 0762 (0:0762)
; For when all the player's pokemon faint.
; Does not print the "blacked out" message.
@@ -745,47 +735,49 @@ 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
+StopMusic:: ; 0788 (0:0788)
+ ld [wMusicHeaderPointer], a
+ call StopAllMusic
.wait
ld a, [wAudioFadeOutControl]
and a
jr nz, .wait
jp StopAllSounds
-HandleFlyWarpOrDungeonWarp::
+HandleFlyWarpOrDungeonWarp:: ; 0794 (0:0794)
call UpdateSprites
call Delay3
xor a
ld [wBattleResult], a
- ld [wWalkBikeSurfState], a
ld [W_ISINBATTLE], 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
-
-LoadPlayerSpriteGraphics::
+Func_07c4:: ; 07c4 (0: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:: ; 07d7 (0:07d7)
; Load sprite graphics based on whether the player is standing, biking, or surfing.
; 0: standing
@@ -820,10 +812,10 @@ LoadPlayerSpriteGraphics::
dec a
jp z, LoadBikePlayerSpriteGraphics
dec a
- jp z, LoadSurfingPlayerSpriteGraphics
+ jp z, LoadSurfingPlayerSpriteGraphics2
jp LoadWalkingPlayerSpriteGraphics
-IsBikeRidingAllowed::
+IsBikeRidingAllowed:: ; 0805 (0:0805)
; The bike can be used on Route 23 and Indigo Plateau,
; or maps with tilesets in BikeRidingTilesets.
; Return carry if biking is allowed.
@@ -853,7 +845,7 @@ IsBikeRidingAllowed::
INCLUDE "data/bike_riding_tilesets.asm"
; load the tile pattern data of the current tileset into VRAM
-LoadTilesetTilePatternData:: ; 09e8 (0:09e8)
+LoadTilesetTilePatternData:: ; 0828 (0:0828)
ld a,[W_TILESETGFXPTR]
ld l,a
ld a,[W_TILESETGFXPTR + 1]
@@ -861,23 +853,16 @@ LoadTilesetTilePatternData:: ; 09e8 (0:09e8)
ld de,vTileset
ld bc,$600
ld a,[W_TILESETBANK]
- jp FarCopyData2
+ 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:: ; 09fc (0:09fc)
+LoadTileBlockMap:: ; 083c (0:083c)
; 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 a,[wd3ad] ; 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
@@ -994,7 +979,7 @@ LoadTileBlockMap:: ; 09fc (0:09fc)
.done
ret
-LoadNorthSouthConnectionsTileMap:: ; 0ade (0:0ade)
+LoadNorthSouthConnectionsTileMap:: ; 0919 (0:0919)
ld c,MAP_BORDER
.loop
push de
@@ -1026,7 +1011,7 @@ LoadNorthSouthConnectionsTileMap:: ; 0ade (0:0ade)
jr nz,.loop
ret
-LoadEastWestConnectionsTileMap:: ; 0b02 (0:0b02)
+LoadEastWestConnectionsTileMap:: ; 093d (0:093d)
push hl
push de
ld c,MAP_BORDER
@@ -1056,9 +1041,8 @@ LoadEastWestConnectionsTileMap:: ; 0b02 (0:0b02)
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
-IsSpriteOrSignInFrontOfPlayer:: ; 0b23 (0:0b23)
+; if so, carry is set. otherwise, carry is cleared
+IsSpriteOrSignInFrontOfPlayer:: ; 095e (0:095e)
xor a
ld [hSpriteIndexOrTextID],a
ld a,[wNumSigns]
@@ -1066,39 +1050,10 @@ IsSpriteOrSignInFrontOfPlayer:: ; 0b23 (0:0b23)
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,W_TILESETTALKINGOVERTILES ; list of tiles that extend talking range (counter tiles)
ld b,3
@@ -1110,12 +1065,11 @@ IsSpriteOrSignInFrontOfPlayer:: ; 0b23 (0:0b23)
dec b
jr nz,.counterTilesLoop
-; part of the above function, but sometimes its called on its own, when signs are irrelevant
-; the caller must zero [hSpriteIndexOrTextID]
-IsSpriteInFrontOfPlayer:: ; 0b6b (0:0b6b)
+; sets carry flag if a sprite is in front of the player, resets if not
+IsSpriteInFrontOfPlayer:: ; 0983 (0:0983)
ld d,$10 ; talking range in pixels (normal range)
-IsSpriteInFrontOfPlayer2:: ; 0b6d (0:0b6d)
- lb bc, $3c, $40 ; Y and X position of player sprite
+IsSpriteInFrontOfPlayer2:: ; 0985 (0:0985)
+ lb bc,$3c, $40 ; Y and X position of player sprite
ld a,[wSpriteStateData1 + 9] ; direction the player is facing
.checkIfPlayerFacingUp
cp SPRITE_FACING_UP
@@ -1152,13 +1106,10 @@ IsSpriteInFrontOfPlayer2:: ; 0b6d (0:0b6d)
ld a,PLAYER_DIR_LEFT
.doneCheckingDirection
ld [wPlayerDirection],a
- ld a,[W_NUMSPRITES] ; number of sprites
- and a
- ret z
-; if there are sprites
ld hl,wSpriteStateData1 + $10
- ld d,a
+; 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)
@@ -1184,6 +1135,7 @@ IsSpriteInFrontOfPlayer2:: ; 0b6d (0:0b6d)
inc e
dec d
jr nz,.spriteLoop
+ xor a
ret
.foundSpriteInFrontOfPlayer
pop hl
@@ -1194,11 +1146,55 @@ IsSpriteInFrontOfPlayer2:: ; 0b6d (0:0b6d)
set 7,[hl]
ld a,e
ld [hSpriteIndexOrTextID],a
+ ld a,[hSpriteIndexOrTextID] ; possible useless read because a already has the value of the read address
+ cp a,$f
+ jr nz,.dontwritetowd436
+ ld a,$FF
+ ld [wd436],a
+.dontwritetowd436
+ scf
+ ret
+
+SignLoop:: ; 09f2 (0:09f2)
+; search if a player is facing a sign
+ ld hl,wd4b1 ; start of sign coordinates
+ ld a,[wd4b0] ; 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,wd4d1 ; 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:: ; 0bd1 (0:0bd1)
+CollisionCheckOnLand:: ; 0a1c (0:0a1c)
ld a,[wd736]
bit 6,a ; is the player jumping?
jr nz,.noCollision
@@ -1210,14 +1206,31 @@ CollisionCheckOnLand:: ; 0bd1 (0:0bd1)
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
+ nop ; ??? why is this in the code
jr nz,.collision
xor a
ld [hSpriteIndexOrTextID],a
call IsSpriteInFrontOfPlayer ; check for sprite collisions again? when does the above check fail to detect a sprite collision?
+ 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
+ cp $f
+ jr nz,.collision
+ call Func_154a
+ 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
@@ -1225,9 +1238,9 @@ CollisionCheckOnLand:: ; 0bd1 (0:0bd1)
jr nc,.noCollision
.collision
ld a,[wChannelSoundIDs + CH4]
- cp a,SFX_COLLISION ; check if collision sound is already playing
+ cp $b4 ; SFX_COLLISION ; check if collision sound is already playing
jr z,.setCarry
- ld a,SFX_COLLISION
+ ld a, $b4 ; SFX_COLLISION
call PlaySound ; play collision sound (if it's not already playing)
.setCarry
scf
@@ -1238,35 +1251,24 @@ CollisionCheckOnLand:: ; 0bd1 (0:0bd1)
; function that checks if the tile in front of the player is passable
; clears carry if it is, sets carry if not
-CheckTilePassable:: ; 0c10 (0:0c10)
+CheckTilePassable:: ; 0a79 (0:0a79)
predef GetTileAndCoordsInFrontOfPlayer ; get tile in front of player
ld a,[wTileInFrontOfPlayer] ; tile in front of player
ld c,a
- ld hl,W_TILESETCOLLISIONPTR ; 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
+ call IsTilePassable
ret
; check if the player is going to jump down a small ledge
; and check for collisions that only occur between certain pairs of tiles
; Input: hl - address of directional collision data
; sets carry if there is a collision and unsets carry if not
-CheckForJumpingAndTilePairCollisions:: ; 0c2a (0:0c2a)
+CheckForJumpingAndTilePairCollisions:: ; 0a86 (0:0a86)
push hl
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
@@ -1276,11 +1278,11 @@ CheckForJumpingAndTilePairCollisions:: ; 0c2a (0:0c2a)
ret nz
; if not jumping
-CheckForTilePairCollisions2:: ; 0c44 (0:0c44)
+CheckForTilePairCollisions2:: ; 0aa0 (0:0aa0)
aCoord 8, 9 ; tile the player is on
ld [wTilePlayerStandingOn],a
-CheckForTilePairCollisions:: ; 0c4a (0:0c4a)
+CheckForTilePairCollisions:: ; 0aa6 (0:0aa6)
ld a,[wTileInFrontOfPlayer]
ld c,a
.tilePairCollisionLoop
@@ -1330,7 +1332,7 @@ CheckForTilePairCollisions:: ; 0c4a (0:0c4a)
; these entries indicate that the player may not cross between tile 1 and tile 2
; it's mainly used to simulate differences in elevation
-TilePairCollisionsLand:: ; 0c7e (0:0c7e)
+TilePairCollisionsLand:: ; 0ada (0:0ada)
db CAVERN, $20, $05
db CAVERN, $41, $05
db FOREST, $30, $2E
@@ -1344,19 +1346,18 @@ TilePairCollisionsLand:: ; 0c7e (0:0c7e)
db FOREST, $5F, $2E
db $FF
-TilePairCollisionsWater:: ; 0ca0 (0:0ca0)
+TilePairCollisionsWater:: ; 0afc (0:0afc)
db FOREST, $14, $2E
db FOREST, $48, $2E
db CAVERN, $14, $05
db $FF
; this builds a tile map from the tile block map based on the current X/Y coordinates of the player's character
-LoadCurrentMapView:: ; 0caa (0:0caa)
+LoadCurrentMapView:: ; 0b06 (0:0b06)
ld a,[H_LOADEDROMBANK]
push af
ld a,[W_TILESETBANK] ; tile data ROM bank
- ld [H_LOADEDROMBANK],a
- ld [MBC1RomBank],a ; switch to ROM bank that contains tile data
+ 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]
@@ -1437,271 +1438,36 @@ LoadCurrentMapView:: ; 0caa (0:0caa)
dec b
jr nz,.rowLoop2
pop af
- ld [H_LOADEDROMBANK],a
- ld [MBC1RomBank],a ; restore previous ROM bank
+ call BankswitchCommon ; restore previous ROM bank
ret
-AdvancePlayerSprite:: ; 0d27 (0:0d27)
- 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,[W_YCOORD]
- add b
- ld [W_YCOORD],a
- ld a,[W_XCOORD]
- add c
- ld [W_XCOORD],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,W_XBLOCKCOORD
- 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,W_YBLOCKCOORD
- 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,[W_CURMAPWIDTH]
- 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,[W_CURMAPWIDTH]
- 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,[W_NUMSPRITES] ; 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:: ; 0e65 (0:0e65)
- ld a,[de]
- add a,$01
- ld [de],a
- ret nc
- inc de
- ld a,[de]
- inc a
- ld [de],a
- ret
-
-MoveTileBlockMapPointerWest:: ; 0e6f (0:0e6f)
- ld a,[de]
- sub a,$01
- ld [de],a
- ret nc
- inc de
- ld a,[de]
- dec a
- ld [de],a
- ret
-
-MoveTileBlockMapPointerSouth:: ; 0e79 (0:0e79)
- 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:: ; 0e85 (0:0e85)
- 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
+AdvancePlayerSprite:: ; 0b7f (0:0b7f)
+ 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
; the portion of the map that was newly exposed due to the player's movement
-ScheduleNorthRowRedraw:: ; 0e91 (0:0e91)
- coord hl, 0, 0
+ScheduleNorthRowRedraw:: ; 0b95 (0:0b95)
+ hlCoord 0, 0
call CopyToRedrawRowOrColumnSrcTiles
ld a,[wMapViewVRAMPointer]
- ld [hRedrawRowOrColumnDest],a
+ ld [H_SCREENEDGEREDRAWADDR],a
ld a,[wMapViewVRAMPointer + 1]
ld [hRedrawRowOrColumnDest + 1],a
ld a,REDRAW_ROW
ld [hRedrawRowOrColumnMode],a
ret
-CopyToRedrawRowOrColumnSrcTiles:: ; 0ea6 (0:0ea6)
+CopyToRedrawRowOrColumnSrcTiles:: ; 0baa (0:0baa)
ld de,wRedrawRowOrColumnSrcTiles
ld c,2 * SCREEN_WIDTH
.loop
@@ -1711,8 +1477,8 @@ CopyToRedrawRowOrColumnSrcTiles:: ; 0ea6 (0:0ea6)
dec c
jr nz,.loop
ret
-
-ScheduleSouthRowRedraw:: ; 0eb2 (0:0eb2)
+
+ScheduleSouthRowRedraw:: ; 0bb6 (0:0bb6)
coord hl, 0, 16
call CopyToRedrawRowOrColumnSrcTiles
ld a,[wMapViewVRAMPointer]
@@ -1731,7 +1497,7 @@ ScheduleSouthRowRedraw:: ; 0eb2 (0:0eb2)
ld [hRedrawRowOrColumnMode],a
ret
-ScheduleEastColumnRedraw:: ; 0ed3 (0:0ed3)
+ScheduleEastColumnRedraw:: ; 0bd6 (0:0bd7)
coord hl, 18, 0
call ScheduleColumnRedrawHelper
ld a,[wMapViewVRAMPointer]
@@ -1749,7 +1515,7 @@ ScheduleEastColumnRedraw:: ; 0ed3 (0:0ed3)
ld [hRedrawRowOrColumnMode],a
ret
-ScheduleColumnRedrawHelper:: ; 0ef2 (0:0ef2)
+ScheduleColumnRedrawHelper:: ; 0bf6 (0:0bf6)
ld de,wRedrawRowOrColumnSrcTiles
ld c,SCREEN_HEIGHT
.loop
@@ -1769,7 +1535,7 @@ ScheduleColumnRedrawHelper:: ; 0ef2 (0:0ef2)
jr nz,.loop
ret
-ScheduleWestColumnRedraw:: ; 0f08 (0:0f08)
+ScheduleWestColumnRedraw:: ; 0c0c (0:0c0c)
coord hl, 0, 0
call ScheduleColumnRedrawHelper
ld a,[wMapViewVRAMPointer]
@@ -1782,7 +1548,7 @@ ScheduleWestColumnRedraw:: ; 0f08 (0:0f08)
; function to write the tiles that make up a tile block to memory
; Input: c = tile block ID, hl = destination address
-DrawTileBlock:: ; 0f1d (0:0f1d)
+DrawTileBlock:: ; 0c21 (0:0c21)
push hl
ld a,[W_TILESETBLOCKSPTR] ; pointer to tiles
ld l,a
@@ -1823,24 +1589,31 @@ DrawTileBlock:: ; 0f1d (0:0f1d)
ret
; function to update joypad state and simulate button presses
-JoypadOverworld:: ; 0f4d (0:0f4d)
+JoypadOverworld:: ; 0c51 (0:0c51)
xor a
ld [wSpriteStateData1 + 3],a
ld [wSpriteStateData1 + 5],a
call RunMapScript
call Joypad
+ call ForceBikeDown
+ call AreInputsSimulated
+ ret
+
+ForceBikeDown:: ; 0c65 (0:0c65)
ld a,[W_FLAGS_D733]
bit 3,a ; check if a trainer wants a challenge
- jr nz,.notForcedDownwards
+ ret nz
ld a,[W_CURMAP]
cp a,ROUTE_17 ; Cycling Road
- jr nz,.notForcedDownwards
+ ret nz
ld a,[hJoyHeld]
and a,D_DOWN | D_UP | D_LEFT | D_RIGHT | B_BUTTON | A_BUTTON
- jr nz,.notForcedDownwards
+ 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
-.notForcedDownwards
+ ret
+
+AreInputsSimulated:: ; 0c7b (0:0c7b)
ld a,[wd730]
bit 7,a
ret z
@@ -1850,24 +1623,15 @@ JoypadOverworld:: ; 0f4d (0:0f4d)
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]
+ 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
ret
+
; if done simulating button presses
.doneSimulating
xor a
@@ -1883,6 +1647,26 @@ JoypadOverworld:: ; 0f4d (0:0f4d)
ld hl,wd730
res 7,[hl]
ret
+
+GetSimulatedInput:: ; 0cb3 (0:0cb3)
+ ld hl,wSimulatedJoypadStatesIndex
+ dec [hl]
+ ld a,[hl]
+ cp a,$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
@@ -1893,7 +1677,7 @@ JoypadOverworld:: ; 0f4d (0:0f4d)
; so the old value of c is used. 2429 is always called before this function,
; 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:: ; 0fb7 (0:0fb7)
+CollisionCheckOnWater:: ; 0cca (0:0cca)
ld a,[wd730]
bit 7,a
jp nz,.noCollision ; return and clear carry if button presses are being simulated
@@ -1901,58 +1685,48 @@ CollisionCheckOnWater:: ; 0fb7 (0:0fb7)
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?
+ jr nz,.collision ; bug?
ld hl,TilePairCollisionsWater
call CheckForJumpingAndTilePairCollisions
jr c,.collision
predef GetTileAndCoordsInFrontOfPlayer ; get tile in front of player (puts it in c and [wTileInFrontOfPlayer])
+ callab IsNextTileShoreOrWater ; 3:6808
+ jr c,.noCollision
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,W_TILESETCOLLISIONPTR ; 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
+ ld c,a
+ call IsTilePassable
+ jr nc,.stopSurfing
.collision
ld a,[wChannelSoundIDs + CH4]
- cp a,SFX_COLLISION ; check if collision sound is already playing
+ cp $b4 ; SFX_COLLISION
jr z,.setCarry
- ld a,SFX_COLLISION
+ 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, [W_CURMAPTILESET] ; 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 [wd431],a
+ ld hl,wd430
+ 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:: ; 101b (0:101b)
+RunMapScript:: ; 0d2c (0:0d2c)
push hl
push de
push bc
@@ -1978,25 +1752,46 @@ RunMapScript:: ; 101b (0:101b)
.return
ret
-LoadWalkingPlayerSpriteGraphics:: ; 104d (0:104d)
- ld de,RedSprite
- ld hl,vNPCSprites
+LoadWalkingPlayerSpriteGraphics:: ; 0d5e (0:0d5e)
+; new sprite copy stuff
+ xor a
+ ld [wd473],a
+ ld b,BANK(RedSprite)
+ ld de,RedSprite ; $4180
+
+LoadSurfingPlayerSpriteGraphics2:: ; 0d69 (0:0d69)
+ 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:: ; 1055 (0:1055)
+
+LoadSurfingPlayerSpriteGraphics:: ; 0d83 (0:0d83)
+ ld b,BANK(RedSprite) ; not sure, but probably same bank (5)
ld de,SeelSprite
- ld hl,vNPCSprites
jr LoadPlayerSpriteGraphicsCommon
-LoadBikePlayerSpriteGraphics:: ; 105d (0:105d)
+LoadBikePlayerSpriteGraphics:: ; 0d8a (0:0d8a)
+ ld b,BANK(RedCyclingSprite)
ld de,RedCyclingSprite
+LoadPlayerSpriteGraphicsCommon:: ; 0d8f (0:0d8f)
ld hl,vNPCSprites
-
-LoadPlayerSpriteGraphicsCommon:: ; 1063 (0:1063)
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
@@ -2006,12 +1801,15 @@ LoadPlayerSpriteGraphicsCommon:: ; 1063 (0:1063)
inc d
.noCarry
set 3,h
- lb bc, BANK(RedSprite), $0c
+ ld c,$c
jp CopyVideoData
; function to load data from the map header
-LoadMapHeader:: ; 107c (0:107c)
+LoadMapHeader:: ; 0dab (0:0dab)
callba MarkTownVisitedAndLoadMissableObjects
+ jr .asm_0dbd
+ callba Func_f0a55 ; 3c:4a55
+.asm_0dbd
ld a,[W_CURMAPTILESET]
ld [wUnusedD119],a
ld a,[W_CURMAP]
@@ -2023,20 +1821,7 @@ LoadMapHeader:: ; 107c (0:107c)
ld [hPreviousTileset],a
bit 7,b
ret nz
- ld hl,MapHeaderPointers
- ld a,[W_CURMAP]
- 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,W_CURMAPTILESET
ld c,$0a
@@ -2110,156 +1895,20 @@ LoadMapHeader:: ; 107c (0:107c)
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
+ 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 [W_NUMSPRITES],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,[W_NUMSPRITES] ; 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,W_MAPSPRITEDATA
- 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,W_MAPSPRITEEXTRADATA
- 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,W_MAPSPRITEEXTRADATA
- 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,W_MAPSPRITEEXTRADATA
- 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
+ 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,.asm_0e73
+ callab Func_fc4fa ; 3f:44fa
+.asm_0e73
+ 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,[W_CURMAPHEIGHT] ; map height in 4x4 tile blocks
add a ; double it
@@ -2272,10 +1921,8 @@ LoadMapHeader:: ; 107c (0:107c)
ld b,$00
ld a,[H_LOADEDROMBANK]
push af
- ld a, BANK(MapSongBanks)
- ld [H_LOADEDROMBANK],a
- ld [MBC1RomBank],a
- ld hl, MapSongBanks
+ switchbank MapSongBanks
+ ld hl, MapSongBanks ; 3f:4000
add hl,bc
add hl,bc
ld a,[hli]
@@ -2283,13 +1930,12 @@ LoadMapHeader:: ; 107c (0:107c)
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:: ; 1238 (0:1238)
+CopyMapConnectionHeader:: ; 0eaa (0:0eaa)
ld c,$0b
.loop
ld a,[hli]
@@ -2299,11 +1945,93 @@ CopyMapConnectionHeader:: ; 1238 (0:1238)
jr nz,.loop
ret
+CopySignData:: ; 0eb3 (0:0eb3)
+ ld de,wd4b1 ; start of sign coords
+ ld bc,wd4d1 ; start of sign text ids
+ ld a,[wd4b0] ; 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:: ; 1241 (0:1241)
ld a,[H_LOADEDROMBANK]
push af
call DisableLCD
+ call ResetMapVariables
+ call LoadTextBoxTilePatterns
+ call LoadMapHeader
+ call InitMapSprites ; load tile pattern data for sprites
+ call LoadScreenRelatedData
+ call CopyMapViewToVRAM
+ ld a,$01
+ ld [wUpdateSpritesEnabled],a
+ call EnableLCD
+ ld b,$09
+ call GoPAL_SET
+ call LoadPlayerSpriteGraphics
+ ld a,[wd732]
+ and a,1 << 4 | 1 << 3 ; fly warp or dungeon warp
+ jr nz,.restoreRomBank
+ ld a,[W_FLAGS_D733]
+ bit 1,a
+ jr nz,.restoreRomBank
+ call Func_21e3 ; music related
+ call Func_2176 ; music related
+.restoreRomBank
+ pop af
+ call BankswitchCommon
+ ret
+
+LoadScreenRelatedData:: ; 0f0c (0:0f0c)
+ call LoadTileBlockMap
+ call LoadTilesetTilePatternData
+ call LoadCurrentMapView
+ ret
+
+Func_0f16:: ; 0f16 (0:0f16)
+ ld a,[H_LOADEDROMBANK]
+ push af
+ call DisableLCD
+ call ResetMapVariables
+ ld a,[W_CURMAP]
+ call SwitchToMapRomBank
+ call LoadScreenRelatedData
+ call CopyMapViewToVRAM
+ ld de,vBGMap1
+ call CopyMapViewToVRAM2
+ call EnableLCD
+ call ReloadMapSpriteTilePatterns
+ pop af
+ call BankswitchCommon
+ jr asm_0f4d
+Func_0f3d:: ; 0f3d (0:0f3d)
+ ld a,[H_LOADEDROMBANK]
+ push af
+ ld a,[W_CURMAP]
+ call SwitchToMapRomBank
+ call LoadTileBlockMap
+ pop af
+ call BankswitchCommon
+asm_0f4d: ; 0f4d (0:0f4d)
+ ld hl, Func_f02da
+ ld b,BANK(Func_f02da) ; 3c:42da
+ jp Bankswitch
+ ret ; useless?
+
+ResetMapVariables:: ; 0f56 (0:0f56)
ld a,$98
ld [wMapViewVRAMPointer + 1],a
xor a
@@ -2312,17 +2040,15 @@ LoadMapData:: ; 1241 (0:1241)
ld [hSCX],a
ld [wWalkCounter],a
ld [wUnusedD119],a
- ld [wWalkBikeSurfStateCopy],a
ld [W_SPRITESETID],a
- call LoadTextBoxTilePatterns
- call LoadMapHeader
- callba InitMapSprites ; load tile pattern data for sprites
- call LoadTileBlockMap
- call LoadTilesetTilePatternData
- call LoadCurrentMapView
+ ld [wWalkBikeSurfStateCopy],a
+ ret
+
+CopyMapViewToVRAM:: ; 0f70 (0:0f70)
; copy current map view to VRAM
- coord hl, 0, 0
ld de,vBGMap0
+CopyMapViewToVRAM2: ; 0f73 (0:0f73)
+ ld hl,wTileMap
ld b,18
.vramCopyLoop
ld c,20
@@ -2332,7 +2058,7 @@ LoadMapData:: ; 1241 (0:1241)
inc e
dec c
jr nz,.vramCopyInnerLoop
- ld a,32 - 20
+ ld a,32 - 20 ; total vram map width in tiles - screen width in tiles
add e
ld e,a
jr nc,.noCarry
@@ -2340,48 +2066,47 @@ LoadMapData:: ; 1241 (0:1241)
.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,[W_FLAGS_D733]
- bit 1,a
- jr nz,.restoreRomBank
- call UpdateMusic6Times
- call PlayDefaultMusicFadeOutCurrent
-.restoreRomBank
- pop af
- ld [H_LOADEDROMBANK],a
- ld [MBC1RomBank],a
ret
; function to switch to the ROM bank that a map is stored in
; Input: a = map number
-SwitchToMapRomBank:: ; 12bc (0:12bc)
+SwitchToMapRomBank:: ; 0f8b (0:0f8b)
push hl
push bc
ld c,a
ld b,$00
- ld a,Bank(MapHeaderBanks)
- call BankswitchHome ; switch to ROM bank 3
+ 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
+ call BankswitchCommon
pop bc
pop hl
ret
-IgnoreInputForHalfSecond: ; 12da (0:12da)
+GetMapHeaderPointer:: ; 0fa7 (0:0fa7)
+ ld a,[H_LOADEDROMBANK]
+ push af
+ switchbank MapHeaderPointers ; 3f:41f2
+ push de
+ ld a,[W_CURMAP]
+ 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: ; 0fc3 (0:0fc3)
ld a, 30
ld [wIgnoreInputCounter], a
ld hl, wd730
@@ -2390,13 +2115,174 @@ IgnoreInputForHalfSecond: ; 12da (0:12da)
ld [hl], a ; set ignore input bit
ret
-ResetUsingStrengthOutOfBattleBit: ; 12e7 (0:12e7)
+ResetUsingStrengthOutOfBattleBit: ; 0fd0 (0:0fd0)
ld hl, wd728
res 0, [hl]
ret
-ForceBikeOrSurf:: ; 12ed (0:12ed)
+ForceBikeOrSurf:: ; 0fd6 (0:0fd6)
ld b, BANK(RedSprite)
ld hl, LoadPlayerSpriteGraphics
call Bankswitch
jp PlayDefaultMusic ; update map/player state?
+
+; Handle the player jumping down
+; a ledge in the overworld.
+HandleMidJump:: ; 0fe1 (0:0fe1)
+ ld a,[wd736]
+ bit 6,a ; jumping down a ledge?
+ ret z
+ callba _HandleMidJump
+ ret
+
+IsSpinning:: ; 0ff0 (0:0ff0)
+ ld a,[wd736]
+ bit 7,a
+ ret z ; no spinning
+ ld b, BANK(LoadSpinnerArrowTiles); spin while moving
+ ld hl,LoadSpinnerArrowTiles ; 11:5077
+ jp Bankswitch
+
+Func_0ffe:: ; 0ffe (0:0ffe)
+ ld hl, Func_fcf0c ; 3f:4f0c
+ ld b, BANK(Func_fcf0c)
+ jp Bankswitch
+
+InitSprites:: ; 1006 (0:1006)
+ ld a,[hli]
+ ld [W_NUMSPRITES],a ; save the number of sprites
+ push hl
+ push de
+ push bc
+ call ZeroSpriteStateData
+ call DisableRegularSprites
+ ld hl,W_MAPSPRITEDATA
+ ld bc,$20
+ xor a
+ call FillMemory
+ pop bc
+ pop de
+ pop hl
+ ld a,[W_NUMSPRITES]
+ 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,$a
+ ld e,a
+ inc c
+ inc c
+ dec b
+ jr nz,.loadSpriteLoop
+ ret
+
+ZeroSpriteStateData:: ; 1050 (0:1050)
+; zero C110-C1EF and C210-C2EF
+; C1F0-C1FF and C2F0-C2FF is probably used for Pikachu
+ ld hl,wSpriteStateData1 + $10
+ ld de,wSpriteStateData2 + $10
+ xor a
+ ld b,$e0
+.loop
+ ld [hli],a
+ ld [de],a
+ inc e
+ dec b
+ jr nz,.loop
+ ret
+
+DisableRegularSprites:: ; 1060 (0:1060)
+; initialize all C100-C1FF sprite entries to disabled (other than player's and pikachu)
+ ld hl,wSpriteStateData1 + $12
+ ld de,$10
+ ld c,$e
+.loop
+ ld [hl],$ff
+ add hl,de
+ dec c
+ jr nz,.loop
+ ret
+
+LoadSprite:: ; 106f (0:106f)
+ push hl
+ ld b,$0
+ ld hl,W_MAPSPRITEDATA
+ 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 a,$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,W_MAPSPRITEEXTRADATA
+ 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,W_MAPSPRITEEXTRADATA
+ 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,W_MAPSPRITEEXTRADATA
+ 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)