diff options
Diffstat (limited to 'home')
-rw-r--r-- | home/audio.asm | 200 | ||||
-rw-r--r-- | home/copy.asm | 70 | ||||
-rw-r--r-- | home/copy2.asm | 136 | ||||
-rw-r--r-- | home/fade.asm | 11 | ||||
-rw-r--r-- | home/init.asm | 13 | ||||
-rw-r--r-- | home/joypad.asm | 39 | ||||
-rw-r--r-- | home/lcdc.asm | 20 | ||||
-rw-r--r-- | home/overworld.asm | 2917 | ||||
-rw-r--r-- | home/pic.asm | 19 | ||||
-rwxr-xr-x | home/pikachu.asm | 114 | ||||
-rw-r--r-- | home/play_time.asm | 71 | ||||
-rw-r--r-- | home/predef.asm | 6 | ||||
-rw-r--r-- | home/serial.asm | 53 | ||||
-rw-r--r-- | home/text.asm | 506 | ||||
-rw-r--r-- | home/vblank.asm | 41 | ||||
-rw-r--r-- | home/vcopy.asm | 68 |
16 files changed, 2238 insertions, 2046 deletions
diff --git a/home/audio.asm b/home/audio.asm index 7c0c5238..8157e758 100644 --- a/home/audio.asm +++ b/home/audio.asm @@ -17,13 +17,14 @@ PlayDefaultMusicFadeOutCurrent:: ld [wLastMusicSoundID], a ld c, 8 ld d, c - PlayDefaultMusicCommon:: ld a, [wWalkBikeSurfState] and a jr z, .walking cp $2 jr z, .surfing + call CheckForNoBikingMusicMap + jr c, .walking ld a, MUSIC_BIKE_RIDING jr .next @@ -34,7 +35,7 @@ PlayDefaultMusicCommon:: ld b, a ld a, d and a ; should current music be faded out first? - ld a, BANK(Music_BikeRiding) + ld a, $1f ; BANK(Music_BikeRiding) jr nz, .next2 ; Only change the audio ROM bank if the current music isn't going to be faded @@ -66,35 +67,32 @@ PlayDefaultMusicCommon:: ld [wNewSoundID], a jp PlaySound -UpdateMusic6Times:: -; This is called when entering a map, before fading out the current music and -; playing the default music (i.e. the map's music or biking/surfing music). - ld a, [wAudioROMBank] - ld b, a - cp BANK(Audio1_UpdateMusic) - jr nz, .checkForAudio2 - -; audio 1 - ld hl, Audio1_UpdateMusic - jr .next - -.checkForAudio2 - cp BANK(Audio2_UpdateMusic) - jr nz, .audio3 - -; audio 2 - ld hl, Audio2_UpdateMusic - jr .next - -.audio3 - ld hl, Audio3_UpdateMusic +CheckForNoBikingMusicMap:: +; probably used to not change music upon getting on bike + ld a, [wCurMap] + cp ROUTE_23 + jr z, .found + cp VICTORY_ROAD_1 + jr z, .found + cp VICTORY_ROAD_2 + jr z, .found + cp VICTORY_ROAD_3 + jr z, .found + cp INDIGO_PLATEAU + jr z, .found + and a + ret +.found + scf + ret -.next - ld c, 6 +UpdateMusic6Times:: + ld c, $6 +UpdateMusicCTimes:: .loop push bc push hl - call Bankswitch + callba Audio1_UpdateMusic ; 2:509d pop hl pop bc dec c @@ -137,7 +135,20 @@ PlayMusic:: ld [wAudioROMBank], a ld [wAudioSavedROMBank], a ld a, b + jr PlaySound + +Func_2223:: + xor a + ld [wChannelSoundIDs + CH4], a + ld [wChannelSoundIDs + CH5], a + ld [wChannelSoundIDs + CH6], a + ld [wChannelSoundIDs + CH7], a + ld [rNR10], a + ret +StopAllMusic:: + ld a, $FF + ld [wNewSoundID], a ; plays music specified by a. If value is $ff, music is stopped PlaySound:: push hl @@ -154,65 +165,130 @@ PlaySound:: ld [wChannelSoundIDs + CH7], a .next ld a, [wAudioFadeOutControl] - and a ; has a fade-out length been specified? + and a jr z, .noFadeOut ld a, [wNewSoundID] - and a ; is the new sound ID 0? - jr z, .done ; if so, do nothing + and a + jr z, .done xor a ld [wNewSoundID], a ld a, [wLastMusicSoundID] - cp $ff ; has the music been stopped? - jr nz, .fadeOut ; if not, fade out the current music -; If it has been stopped, start playing the new music immediately. + cp $ff + jr nz, .fadeOut xor a ld [wAudioFadeOutControl], a .noFadeOut xor a ld [wNewSoundID], a + call DetermineAudioFunction + jr .done + +.fadeOut + ld a, b + ld [wLastMusicSoundID], a + ld a, [wAudioFadeOutControl] + ld [wAudioFadeOutCounterReloadValue], a + ld [wAudioFadeOutCounter], a + ld a, b + ld [wAudioFadeOutControl], a +.done + pop bc + pop de + pop hl + ret + +GetNextMusicByte:: ld a, [H_LOADEDROMBANK] - ld [hSavedROMBank], a + push af ld a, [wAudioROMBank] - ld [H_LOADEDROMBANK], a - ld [MBC1RomBank], a - cp BANK(Audio1_PlaySound) - jr nz, .checkForAudio2 + call BankswitchCommon + ld d, $0 + ld a, c + add a + ld e, a + ld hl, wChannelCommandPointers + add hl, de + ld a, [hli] + ld e, a + ld a, [hld] + ld d, a + ld a, [de] + inc de + ld [hl], e + inc hl + ld [hl], d + ld e, a + pop af + call BankswitchCommon + ld a, e + ret + +InitMusicVariables:: + push hl + push de + push bc + homecall Audio2_InitMusicVariables ; 8:59f8 + pop bc + pop de + pop hl + ret + +InitSFXVariables:: + push hl + push de + push bc + homecall Audio2_InitSFXVariables ; 8:5ab7 + pop bc + pop de + pop hl + ret -; audio 1 +StopAllAudio:: + push hl + push de + push bc + homecall Audio2_StopAllAudio + pop bc + pop de + pop hl + ret + +DetermineAudioFunction:: + ld a, [H_LOADEDROMBANK] + push af + ld a, [wAudioROMBank] + call BankswitchCommon +; determine the audio function, based on the bank + cp BANK(Audio1_PlaySound) + jr nz, .checkForBank08 +; bank 02 (audio 1) ld a, b call Audio1_PlaySound - jr .next2 + jr .done -.checkForAudio2 +.checkForBank08 cp BANK(Audio2_PlaySound) - jr nz, .audio3 - -; audio 2 + jr nz, .checkForBank1F +; bank 08 (audio 2) ld a, b call Audio2_PlaySound - jr .next2 + jr .done -.audio3 +.checkForBank1F + cp BANK(Audio3_PlaySound) + jr nz, .bank20 +; bank 1f (audio 3) ld a, b call Audio3_PlaySound - -.next2 - ld a, [hSavedROMBank] - ld [H_LOADEDROMBANK], a - ld [MBC1RomBank], a jr .done -.fadeOut +.bank20 +; invalid banks will default to XX:6bd4 +; this is seen when encountering Missingno, as its sprite dimensions overflow to wAudioROMBank ld a, b - ld [wLastMusicSoundID], a - ld a, [wAudioFadeOutControl] - ld [wAudioFadeOutCounterReloadValue], a - ld [wAudioFadeOutCounter], a - ld a, b - ld [wAudioFadeOutControl], a - + call Audio4_PlaySound .done - pop bc - pop de - pop hl + pop af + call BankswitchCommon ret + diff --git a/home/copy.asm b/home/copy.asm index be9c8c0c..4f1d5017 100644 --- a/home/copy.asm +++ b/home/copy.asm @@ -1,24 +1,74 @@ FarCopyData:: ; Copy bc bytes from a:hl to de. - ld [wBuffer], a + ld [wFarCopyDataSavedROMBank], a ld a, [H_LOADEDROMBANK] push af - ld a, [wBuffer] - ld [H_LOADEDROMBANK], a - ld [MBC1RomBank], a + ld a, [wFarCopyDataSavedROMBank] + call BankswitchCommon call CopyData pop af - ld [H_LOADEDROMBANK], a - ld [MBC1RomBank], a + call BankswitchCommon ret CopyData:: ; Copy bc bytes from hl to de. + ld a,b + and a + jr z, .copybytes + ld a,c + and a ; is lower byte 0 + jr z, .loop + inc b ; if not, increment b as there are <$100 bytes to copy +.loop + call .copybytes + dec b + jr nz,.loop + ret + +.copybytes ; 00c1 ld a, [hli] ld [de], a inc de - dec bc - ld a, c - or b - jr nz, CopyData + dec c + jr nz, .copybytes ret + +CopyVideoDataAlternate:: + ld a, [rLCDC] + bit 7,a ; LCD enabled? + jp nz, CopyVideoData ; if yes, then copy video data + push hl + ld h,d + ld l,e + pop de + ld a,b ; save bank + push af + swap c + ld a,$f + and c + ld b,a + ld a,$f0 + and c + ld c,a + pop af + jp FarCopyData + +CopyVideoDataDoubleAlternate:: + ld a, [rLCDC] + bit 7,a ; LCD enabled? + jp nz, CopyVideoDataDouble ; if yes, then copy video data + push de + ld d,h + ld e,l + ld a,b + push af ; save bank to switch to + ld h,$0 + ld l,c + add hl,hl ; get raw length of bytes to copy + add hl,hl + add hl,hl + ld b,h + ld c,l + pop af + pop hl + jp FarCopyDataDouble diff --git a/home/copy2.asm b/home/copy2.asm index 830440b0..ad47c4a0 100644 --- a/home/copy2.asm +++ b/home/copy2.asm @@ -1,62 +1,36 @@ -FarCopyData2:: -; Identical to FarCopyData, but uses hROMBankTemp -; as temp space instead of wBuffer. - ld [hROMBankTemp],a - ld a,[H_LOADEDROMBANK] - push af - ld a,[hROMBankTemp] - ld [H_LOADEDROMBANK],a - ld [MBC1RomBank],a - call CopyData - pop af - ld [H_LOADEDROMBANK],a - ld [MBC1RomBank],a - ret - -FarCopyData3:: -; Copy bc bytes from a:de to hl. - ld [hROMBankTemp],a - ld a,[H_LOADEDROMBANK] - push af - ld a,[hROMBankTemp] - ld [H_LOADEDROMBANK],a - ld [MBC1RomBank],a - push hl - push de - push de - ld d,h - ld e,l - pop hl - call CopyData - pop de - pop hl - pop af - ld [H_LOADEDROMBANK],a - ld [MBC1RomBank],a - ret - FarCopyDataDouble:: ; Expand bc bytes of 1bpp image data -; from a:hl to 2bpp data at de. - ld [hROMBankTemp],a +; from a:de to 2bpp data at hl. + ld [wFarCopyDataSavedROMBank],a ld a,[H_LOADEDROMBANK] push af - ld a,[hROMBankTemp] - ld [H_LOADEDROMBANK],a - ld [MBC1RomBank],a -.loop - ld a,[hli] - ld [de],a - inc de - ld [de],a - inc de - dec bc + ld a,[wFarCopyDataSavedROMBank] + call BankswitchCommon + ld a,h ; swap hl and de + ld h,d + ld d,a + ld a,l + ld l,e + ld e,a + ld a,b + and a + jr z,.eightbitcopyamount ld a,c - or b - jr nz,.loop + and a ; multiple of $100 + jr z, .expandloop ; if so, do not increment b because the first instance of dec c results in underflow +.eightbitcopyamount + inc b +.expandloop + ld a,[de] + inc de + ld [hli],a + ld [hli],a + dec c + jr nz, .expandloop + dec b + jr nz, .expandloop pop af - ld [H_LOADEDROMBANK],a - ld [MBC1RomBank],a + call BankswitchCommon ret CopyVideoData:: @@ -70,11 +44,10 @@ CopyVideoData:: ld [H_AUTOBGTRANSFERENABLED], a ld a, [H_LOADEDROMBANK] - ld [hROMBankTemp], a + push af ld a, b - ld [H_LOADEDROMBANK], a - ld [MBC1RomBank], a + call BankswitchCommon ld a, e ld [H_VBCOPYSRC], a @@ -94,9 +67,8 @@ CopyVideoData:: .done ld [H_VBCOPYSIZE], a call DelayFrame - ld a, [hROMBankTemp] - ld [H_LOADEDROMBANK], a - ld [MBC1RomBank], a + pop af + call BankswitchCommon pop af ld [H_AUTOBGTRANSFERENABLED], a ret @@ -119,11 +91,10 @@ CopyVideoDataDouble:: xor a ; disable auto-transfer while copying ld [H_AUTOBGTRANSFERENABLED], a ld a, [H_LOADEDROMBANK] - ld [hROMBankTemp], a + push af ld a, b - ld [H_LOADEDROMBANK], a - ld [MBC1RomBank], a + call BankswitchCommon ld a, e ld [H_VBCOPYDOUBLESRC], a @@ -143,9 +114,8 @@ CopyVideoDataDouble:: .done ld [H_VBCOPYDOUBLESIZE], a call DelayFrame - ld a, [hROMBankTemp] - ld [H_LOADEDROMBANK], a - ld [MBC1RomBank], a + pop af + call BankswitchCommon pop af ld [H_AUTOBGTRANSFERENABLED], a ret @@ -159,6 +129,42 @@ CopyVideoDataDouble:: ld c, a jr .loop +FillMemory:: + push af + ld a,b + and a + jr z, .eightbitcopyamount + ld a,c + and a + jr z, .mulitpleof0x100 +.eightbitcopyamount + inc b +.mulitpleof0x100 + pop af +.loop + ld [hli],a + dec c + jr nz, .loop + dec b + jr nz, .loop + ret + +GetFarByte:: +; get a byte from a:hl +; and return it in a + push bc + ld b, a + ld a, [H_LOADEDROMBANK] + push af + ld a, b + call BankswitchCommon + ld b, [hl] + pop af + call BankswitchCommon + ld a, b + pop bc + ret + ClearScreenArea:: ; Clear tilemap area cxb at hl. ld a, " " ; blank tile diff --git a/home/fade.asm b/home/fade.asm index 08e087b4..1259f92b 100644 --- a/home/fade.asm +++ b/home/fade.asm @@ -1,7 +1,7 @@ ; These routines manage gradual fading ; (e.g., entering a doorway) LoadGBPal:: - ld a, [wMapPalOffset] ;tells if cur.map is dark (requires HM5_FLASH?) + ld a, [wMapPalOffset] ; tells if wCurMap is dark (requires HM5_FLASH?) ld b, a ld hl, FadePal4 ld a, l @@ -16,6 +16,9 @@ LoadGBPal:: ld [rOBP0], a ld a, [hli] ld [rOBP1], a + call UpdateGBCPal_BGP + call UpdateGBCPal_OBP0 + call UpdateGBCPal_OBP1 ret GBFadeInFromBlack:: @@ -34,6 +37,9 @@ GBFadeIncCommon: ld [rOBP0], a ld a, [hli] ld [rOBP1], a + call UpdateGBCPal_BGP + call UpdateGBCPal_OBP0 + call UpdateGBCPal_OBP1 ld c, 8 call DelayFrames dec b @@ -56,6 +62,9 @@ GBFadeDecCommon: ld [rOBP0], a ld a, [hld] ld [rBGP], a + call UpdateGBCPal_BGP + call UpdateGBCPal_OBP0 + call UpdateGBCPal_OBP1 ld c, 8 call DelayFrames dec b diff --git a/home/init.asm b/home/init.asm index cb5c6583..6aa14608 100644 --- a/home/init.asm +++ b/home/init.asm @@ -3,8 +3,6 @@ SoftReset:: call GBPalWhiteOut ld c, 32 call DelayFrames - ; fallthrough - Init:: ; Program init. @@ -51,10 +49,10 @@ rLCDC_DEFAULT EQU %11100011 or c jr nz, .loop - call ClearVram + call ClearVram ; 1dc6 ld hl, $ff80 - ld bc, $ffff - $ff80 + ld bc, $fffe - $ff80 call FillMemory call ClearSprites @@ -70,6 +68,8 @@ rLCDC_DEFAULT EQU %11100011 ld [hSCX], a ld [hSCY], a ld [rIF], a + ld [wc0f3], a + ld [wc0f4], a ld a, 1 << VBLANK + 1 << TIMER + 1 << SERIAL ld [rIE], a @@ -126,12 +126,11 @@ ClearVram: StopAllSounds:: - ld a, BANK(Audio1_UpdateMusic) + ld a, $2 ld [wAudioROMBank], a ld [wAudioSavedROMBank], a xor a ld [wAudioFadeOutControl], a ld [wNewSoundID], a ld [wLastMusicSoundID], a - dec a - jp PlaySound + jp StopAllMusic diff --git a/home/joypad.asm b/home/joypad.asm deleted file mode 100644 index 2002bb29..00000000 --- a/home/joypad.asm +++ /dev/null @@ -1,39 +0,0 @@ -ReadJoypad:: -; Poll joypad input. -; Unlike the hardware register, button -; presses are indicated by a set bit. - - ld a, 1 << 5 ; select direction keys - ld c, 0 - - ld [rJOYP], a - rept 6 - ld a, [rJOYP] - endr - cpl - and %1111 - swap a - ld b, a - - ld a, 1 << 4 ; select button keys - ld [rJOYP], a - rept 10 - ld a, [rJOYP] - endr - cpl - and %1111 - or b - - ld [hJoyInput], a - - ld a, 1 << 4 + 1 << 5 ; deselect keys - ld [rJOYP], a - ret - -Joypad:: -; Update the joypad state variables: -; [hJoyReleased] keys released since last time -; [hJoyPressed] keys pressed since last time -; [hJoyHeld] currently pressed keys - homecall _Joypad - ret diff --git a/home/lcdc.asm b/home/lcdc.asm new file mode 100644 index 00000000..6172dd0d --- /dev/null +++ b/home/lcdc.asm @@ -0,0 +1,20 @@ +LCDC:: + push af + ld a, [hLCDCPointer] ; doubles as enabling byte + and a + jr z, .noLCDCInterrupt + push hl + ; [C700 + [rLY]] --> [FF00 + [hLCDCPointer]] + ld a, [rLY] + ld l, a + ld h, wLYOverrides / $100 + ld h, [hl] ; h != not part of pointer + ld a, [hLCDCPointer] + ld l, a + ld a, h + ld h, $ff + ld [hl], a + pop hl +.noLCDCInterrupt + pop af + reti 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) diff --git a/home/pic.asm b/home/pic.asm index 15ee53ad..d0645a8c 100644 --- a/home/pic.asm +++ b/home/pic.asm @@ -5,16 +5,13 @@ UncompressSpriteData:: ld a, [H_LOADEDROMBANK] push af ld a, b - ld [H_LOADEDROMBANK], a - ld [MBC1RomBank], a - ld a, $a - ld [$0], a - xor a - ld [$4000], a + call BankswitchCommon + ld a,$0 + call SwitchSRAMBankAndLatchClockData call _UncompressSpriteData + call PrepareRTCDataAndDisableSRAM pop af - ld [H_LOADEDROMBANK], a - ld [MBC1RomBank], a + call BankswitchCommon ret ; initializes necessary data to load a sprite and runs UncompressSpriteDataLoop @@ -531,15 +528,15 @@ ReverseNybble:: ld de, NybbleReverseTable add e ld e, a - jr nc, .asm_283f + jr nc, .asm_2735 inc d -.asm_283f +.asm_2735 ld a, [de] ret ; resets sprite buffer pointers to buffer 1 and 2, depending on wSpriteLoadFlags ResetSpriteBufferPointers:: - ld a, [wSpriteLoadFlags] + ld a, [wSpriteLoadFlags] ; wd0a8 bit 0, a jr nz, .buffer2Selected ld de, sSpriteBuffer1 diff --git a/home/pikachu.asm b/home/pikachu.asm new file mode 100755 index 00000000..d16e95db --- /dev/null +++ b/home/pikachu.asm @@ -0,0 +1,114 @@ +Func_1510:: + push hl + ld hl, wPikachuOverworldStateFlags + set 7, [hl] + ld hl, wPikachuSpriteImageIdx ; pikachu data? + ld [hl], $ff + pop hl + ret + +Func_151d:: + push hl + ld hl, wPikachuOverworldStateFlags + res 7, [hl] + pop hl + ret + +EnablePikachuOverworldSpriteDrawing:: + push hl + ld hl, wPikachuOverworldStateFlags + res 3, [hl] + pop hl + ret + +DisablePikachuOverworldSpriteDrawing:: + push hl + ld hl, wPikachuOverworldStateFlags + set 3, [hl] + ld hl, wPikachuSpriteImageIdx ; pikachu data? + ld [hl], $ff + pop hl + ret + +DisablePikachuFollowingPlayer:: + push hl + ld hl, wPikachuOverworldStateFlags + set 1, [hl] + pop hl + ret + +EnablePikachuFollowingPlayer:: + push hl + ld hl, wPikachuOverworldStateFlags + res 1, [hl] + pop hl + ret + +CheckPikachuFollowingPlayer:: + push hl + ld hl, wPikachuOverworldStateFlags + bit 1, [hl] + pop hl + ret + +SpawnPikachu:: + ld a, [hl] + dec a + swap a + ld [hTilePlayerStandingOn], a + homecall SpawnPikachu_ ; 3f:46d5 + ret + +Pikachu_IsInArray:: + ld b, $0 + ld c, a +.loop + inc b + ld a, [hli] + cp $ff + jr z, .not_in_array + cp c + jr nz, .loop + dec b + dec hl + scf + ret + +.not_in_array + dec b + dec hl + and a + ret + +GetPikachuMovementScriptByte:: + push hl + push bc + ld a, [H_LOADEDROMBANK] + push af + ld a, [wPikachuMovementScriptBank] + call BankswitchCommon + ld hl, wPikachuMovementScriptAddress + ld c, [hl] + inc hl + ld b, [hl] + ld a, [bc] + inc bc + ld [hl], b + dec hl + ld [hl], c + ld c, a + pop af + call BankswitchCommon + ld a, c + pop bc + pop hl + ret + +ApplyPikachuMovementData:: + ld a, [H_LOADEDROMBANK] + ld b, a + push af + callbs ApplyPikachuMovementData_ + pop af + call BankswitchCommon + ret diff --git a/home/play_time.asm b/home/play_time.asm new file mode 100644 index 00000000..47b2a690 --- /dev/null +++ b/home/play_time.asm @@ -0,0 +1,71 @@ +TrackPlayTime: + call CountDownIgnoreInputBitReset + ld hl, wd47a + bit 0, [hl] + jr nz, .maxIGT + ld a,[wd732] + bit 0,a + ret z + ld a, [wPlayTimeMaxed] + and a + ret nz + ld a, [wPlayTimeFrames] + inc a + ld [wPlayTimeFrames], a + cp 60 + ret nz + xor a + ld [wPlayTimeFrames], a + ld a, [wPlayTimeSeconds] + inc a + ld [wPlayTimeSeconds], a + cp 60 + ret nz + xor a + ld [wPlayTimeSeconds], a + ld a, [wPlayTimeMinutes] + inc a + ld [wPlayTimeMinutes], a + cp 60 + ret nz + xor a + ld [wPlayTimeMinutes], a + ld a, [wPlayTimeHours] + inc a + ld [wPlayTimeHours], a + cp $ff + ret nz + ld hl, wd47a + set 0, [hl] +.maxIGT + ld a, 59 + ld [wPlayTimeSeconds], a + ld [wPlayTimeMinutes], a + ld a, $ff + ld [wPlayTimeHours], a + ld [wPlayTimeMaxed], a + ret + +CountDownIgnoreInputBitReset: + ld a, [wIgnoreInputCounter] + and a + jr nz, .asm_1f5e + ld a, $ff + jr .asm_1f5f +.asm_1f5e + dec a +.asm_1f5f + ld [wIgnoreInputCounter], a + and a + ret nz + ld a, [wd730] + res 1, a + res 2, a + bit 5, a + res 5, a + ld [wd730], a + ret z + xor a + ld [hJoyPressed], a + ld [hJoyHeld], a + ret diff --git a/home/predef.asm b/home/predef.asm index 2fac9aca..c55760d7 100644 --- a/home/predef.asm +++ b/home/predef.asm @@ -19,8 +19,7 @@ Predef:: call GetPredefPointer ld a, [wPredefBank] - ld [H_LOADEDROMBANK], a - ld [MBC1RomBank], a + call BankswitchCommon ld de, .done push de @@ -28,8 +27,7 @@ Predef:: .done pop af - ld [H_LOADEDROMBANK], a - ld [MBC1RomBank], a + call BankswitchCommon ret GetPredefRegisters:: diff --git a/home/serial.asm b/home/serial.asm index 7a515118..508148df 100644 --- a/home/serial.asm +++ b/home/serial.asm @@ -3,6 +3,9 @@ Serial:: push bc push de push hl + ld a, [wPrinterConnectionOpen] + bit 0, a + jp nz, PrinterSerial__ ld a, [hSerialConnectionStatus] inc a jr z, .connectionNotYetEstablished @@ -91,79 +94,79 @@ Serial_ExchangeByte:: ld [hSerialReceivedNewData], a ld a, [hSerialConnectionStatus] cp USING_INTERNAL_CLOCK - jr nz, .asm_21a7 + jr nz, .asm_2003 ld a, START_TRANSFER_INTERNAL_CLOCK ld [rSC], a -.asm_21a7 +.asm_2003 ld a, [hSerialReceivedNewData] and a - jr nz, .asm_21f1 + jr nz, .asm_204d ld a, [hSerialConnectionStatus] cp USING_EXTERNAL_CLOCK - jr nz, .asm_21cc + jr nz, .asm_2028 call IsUnknownCounterZero - jr z, .asm_21cc + jr z, .asm_2028 call WaitLoop_15Iterations push hl ld hl, wUnknownSerialCounter + 1 inc [hl] - jr nz, .asm_21c3 + jr nz, .asm_201f dec hl inc [hl] -.asm_21c3 +.asm_201f pop hl call IsUnknownCounterZero - jr nz, .asm_21a7 + jr nz, .asm_2003 jp SetUnknownCounterToFFFF -.asm_21cc +.asm_2028 ld a, [rIE] and (1 << SERIAL) | (1 << TIMER) | (1 << LCD_STAT) | (1 << VBLANK) cp (1 << SERIAL) - jr nz, .asm_21a7 + jr nz, .asm_2003 ld a, [wUnknownSerialCounter2] dec a ld [wUnknownSerialCounter2], a - jr nz, .asm_21a7 + jr nz, .asm_2003 ld a, [wUnknownSerialCounter2 + 1] dec a ld [wUnknownSerialCounter2 + 1], a - jr nz, .asm_21a7 + jr nz, .asm_2003 ld a, [hSerialConnectionStatus] cp USING_EXTERNAL_CLOCK - jr z, .asm_21f1 + jr z, .asm_204d ld a, 255 .waitLoop dec a jr nz, .waitLoop -.asm_21f1 +.asm_204d xor a ld [hSerialReceivedNewData], a ld a, [rIE] and (1 << SERIAL) | (1 << TIMER) | (1 << LCD_STAT) | (1 << VBLANK) sub (1 << SERIAL) - jr nz, .asm_2204 + jr nz, .asm_2060 ld [wUnknownSerialCounter2], a ld a, $50 ld [wUnknownSerialCounter2 + 1], a -.asm_2204 +.asm_2060 ld a, [hSerialReceiveData] cp SERIAL_NO_DATA_BYTE ret nz call IsUnknownCounterZero - jr z, .asm_221f + jr z, .asm_207b push hl ld hl, wUnknownSerialCounter + 1 ld a, [hl] dec a ld [hld], a inc a - jr nz, .asm_2219 + jr nz, .asm_2075 dec [hl] -.asm_2219 +.asm_2075 pop hl call IsUnknownCounterZero jr z, SetUnknownCounterToFFFF -.asm_221f +.asm_207b ld a, [rIE] and (1 << SERIAL) | (1 << TIMER) | (1 << LCD_STAT) | (1 << VBLANK) cp (1 << SERIAL) @@ -225,7 +228,7 @@ Serial_ExchangeLinkMenuSelection:: Serial_PrintWaitingTextAndSyncAndExchangeNybble:: call SaveScreenTilesToBuffer1 - callab PrintWaitingText + callab PrintWaitingText ; 1:4b89 call Serial_SyncAndExchangeNybble jp LoadScreenTilesFromBuffer1 @@ -310,3 +313,11 @@ Serial_TryEstablishingExternallyClockedConnection:: ld a, START_TRANSFER_EXTERNAL_CLOCK ld [rSC], a ret + +PrinterSerial__:: + call PrinterSerial + pop hl + pop de + pop bc + pop af + reti diff --git a/home/text.asm b/home/text.asm index e9c0efdd..9c661f21 100644 --- a/home/text.asm +++ b/home/text.asm @@ -18,7 +18,7 @@ TextBoxBorder:: .next push hl ld a, "│" - ld [hli],a + ld [hli], a ld a, " " call NPlaceChar ld [hl], "│" @@ -49,89 +49,79 @@ NPlaceChar:: PlaceString:: push hl PlaceNextChar:: - ld a,[de] + ld a, [de] cp "@" - jr nz,.PlaceText - ld b,h - ld c,l + jr nz, Char4ETest + ld b, h + ld c, l pop hl ret -.PlaceText - cp $4E - jr nz,.next - ld bc,SCREEN_WIDTH * 2 - ld a,[hFlags_0xFFF6] - bit 2,a - jr z,.next2 - ld bc,SCREEN_WIDTH +Char4ETest:: + cp $4E ; next + jr nz, .next + ld bc, 2 * SCREEN_WIDTH + ld a, [hFlags_0xFFFA] + bit 2, a + jr z, .next2 + ld bc, SCREEN_WIDTH .next2 pop hl - add hl,bc + add hl, bc push hl - jp PlaceNextChar_inc + jp PlaceNextChar_inc ; 17b6 .next - cp $4F - jr nz,.next3 + cp $4F ; line + jr nz, .next3 pop hl coord hl, 1, 16 push hl jp PlaceNextChar_inc .next3 ; Check against a dictionary +dict: macro +if \1 == 0 and a - jp z,Char00 - cp $4C - jp z,Char4C - cp $4B - jp z,Char4B - cp $51 - jp z,Char51 - cp $49 - jp z,Char49 - cp $52 - jp z,Char52 - cp $53 - jp z,Char53 - cp $54 - jp z,Char54 - cp $5B - jp z,Char5B - cp $5E - jp z,Char5E - cp $5C - jp z,Char5C - cp $5D - jp z,Char5D - cp $55 - jp z,Char55 - cp $56 - jp z,Char56 - cp $57 - jp z,Char57 - cp $58 - jp z,Char58 - cp $4A - jp z,Char4A - cp $5F - jp z,Char5F - cp $59 - jp z,Char59 - cp $5A - jp z,Char5A - ld [hli],a +else + cp \1 +endc + jp z, \2 +endm + + dict $00, Char00 ; error + dict $4C, Char4C ; autocont + dict $4B, Char4B ; cont_ + dict $51, Char51 ; para + dict $49, Char49 ; page + dict $52, Char52 ; player + dict $53, Char53 ; rival + dict $54, Char54 ; POKé + dict $5B, Char5B ; PC + dict $5E, Char5E ; ROCKET + dict $5C, Char5C ; TM + dict $5D, Char5D ; TRAINER + dict $55, Char55 ; cont + dict $56, Char56 ; 6 dots + dict $57, Char57 ; done + dict $58, Char58 ; prompt + dict $4A, Char4A ; PKMN + dict $5F, Char5F ; dex + dict $59, Char59 ; TARGET + dict $5A, Char5A ; USER + + ld [hli], a call PrintLetterDelay PlaceNextChar_inc:: inc de jp PlaceNextChar Char00:: - ld b,h - ld c,l + ld b, h + ld c, l pop hl - ld de,Char00Text + ld de, Char00Text dec de ret @@ -141,47 +131,47 @@ Char00Text:: ; “%d ERROR.” Char52:: ; player’s name push de - ld de,wPlayerName + ld de, wPlayerName jr FinishDTE Char53:: ; rival’s name push de - ld de,wRivalName + ld de, wRivalName jr FinishDTE Char5D:: ; TRAINER push de - ld de,Char5DText + ld de, Char5DText jr FinishDTE Char5C:: ; TM push de - ld de,Char5CText + ld de, Char5CText jr FinishDTE Char5B:: ; PC push de - ld de,Char5BText + ld de, Char5BText jr FinishDTE Char5E:: ; ROCKET push de - ld de,Char5EText + ld de, Char5EText jr FinishDTE Char54:: ; POKé push de - ld de,Char54Text + ld de, Char54Text jr FinishDTE Char56:: ; …… push de - ld de,Char56Text + ld de, Char56Text jr FinishDTE Char4A:: ; PKMN push de - ld de,Char4AText + ld de, Char4AText jr FinishDTE Char59:: @@ -190,7 +180,7 @@ Char59:: ; or ; player active monster’s name ; (like Char5A but flipped) - ld a,[H_WHOSETURN] + ld a, [H_WHOSETURN] xor 1 jr MonsterNameCharsCommon @@ -199,27 +189,26 @@ Char5A:: ; player active monster’s name ; or ; enemy active monster’s name, prefixed with “Enemy ” - ld a,[H_WHOSETURN] + ld a, [H_WHOSETURN] MonsterNameCharsCommon:: push de and a - jr nz,.Enemy - ld de,wBattleMonNick ; player active monster name + jr nz, .Enemy + ld de, wBattleMonNick ; player active monster name jr FinishDTE .Enemy ; print “Enemy ” - ld de,Char5AText + ld de, Char5AText call PlaceString - - ld h,b - ld l,c - ld de,wEnemyMonNick ; enemy active monster name + ld h, b + ld l, c + ld de, wEnemyMonNick ; enemy active monster name FinishDTE:: call PlaceString - ld h,b - ld l,c + ld h, b + ld l, c pop de inc de jp PlaceNextChar @@ -239,76 +228,83 @@ Char56Text:: Char5AText:: db "Enemy @" Char4AText:: - db $E1,$E2,"@" ; PKMN + db $E1, $E2, "@" ; PKMN Char55:: push de - ld b,h - ld c,l - ld hl,Char55Text - call TextCommandProcessor - ld h,b - ld l,c + ld b, h + ld c, l + ld hl, Char55Text + call TextCommandProcessor ; 1919 + ld h, b + ld l, c pop de inc de jp PlaceNextChar Char55Text:: ; equivalent to Char4B - TX_FAR _Char55Text + TX_FAR _Char55Text ; a0c73 (28:4c73) db "@" Char5F:: ; ends a Pokédex entry - ld [hl],"." + ld [hl], "." pop hl ret -Char58:: - ld a,[wLinkState] +Char58:: ; 1863 (0:1863) prompt + ld a, [wLinkState] cp LINK_STATE_BATTLING - jp z,Next1AA2 - ld a,$EE + jp z, .next + ld a, $EE Coorda 18, 16 -Next1AA2:: - call ProtectedDelay3 - call ManualTextScroll - ld a, " " +.next ; 1870 (0:1870) + call ProtectedDelay3 ; 1913 + call ManualTextScroll ; 388e + ld a, " " ; space Coorda 18, 16 -Char57:: +Char57:: ; 1aad (0:1aad) done pop hl - ld de,Char58Text + ld de, Char58Text dec de ret Char58Text:: db "@" -Char51:: +Char51:: ; 1882 (0:1882) para push de - ld a,$EE + ld a, $EE Coorda 18, 16 call ProtectedDelay3 call ManualTextScroll coord hl, 1, 13 lb bc, 4, 18 call ClearScreenArea - ld c,20 + ld c, 20 call DelayFrames pop de coord hl, 1, 14 jp PlaceNextChar_inc Char49:: + ld a, [hFlags_0xFFFA] + bit 3, a + jr z, .Char49 + ld a, $4e + jp Char4ETest + +.Char49 push de - ld a,$EE + ld a, $EE Coorda 18, 16 call ProtectedDelay3 call ManualTextScroll coord hl, 1, 10 lb bc, 7, 18 call ClearScreenArea - ld c,20 + ld c, 20 call DelayFrames pop de pop hl @@ -317,7 +313,7 @@ Char49:: jp PlaceNextChar_inc Char4B:: - ld a,$EE + ld a, $EE Coorda 18, 16 call ProtectedDelay3 push de @@ -328,36 +324,36 @@ Char4B:: ;fall through Char4C:: push de - call Next1B18 - call Next1B18 + call ScrollTextUpOneLine ; 18f1 + call ScrollTextUpOneLine coord hl, 1, 16 pop de jp PlaceNextChar_inc -Next1B18:: +ScrollTextUpOneLine:: coord hl, 0, 14 coord de, 0, 13 - ld b,60 + ld b, 60 .next - ld a,[hli] - ld [de],a + ld a, [hli] + ld [de], a inc de dec b - jr nz,.next + jr nz, .next coord hl, 1, 16 ld a, " " - ld b,SCREEN_WIDTH - 2 + ld b, SCREEN_WIDTH - 2 .next2 - ld [hli],a + ld [hli], a dec b - jr nz,.next2 + jr nz, .next2 ; wait five frames - ld b,5 + ld b, 5 .WaitFrame call DelayFrame dec b - jr nz,.WaitFrame + jr nz, .WaitFrame ret @@ -368,42 +364,42 @@ ProtectedDelay3:: ret TextCommandProcessor:: - ld a,[wLetterPrintingDelayFlags] + ld a, [wLetterPrintingDelayFlags] push af - set 1,a - ld e,a - ld a,[$fff4] + set 1, a + ld e, a + ld a, [$fff9] xor e - ld [wLetterPrintingDelayFlags],a - ld a,c - ld [wUnusedCC3A],a - ld a,b - ld [wUnusedCC3B],a + ld [wLetterPrintingDelayFlags], a + ld a, c + ld [wTextDestinationTileAddrBuffer], a + ld a, b + ld [wTextDestinationTileAddrBuffer + 1], a NextTextCommand:: - ld a,[hli] + ld a, [hli] cp a, "@" ; terminator - jr nz,.doTextCommand + jr nz, .doTextCommand pop af - ld [wLetterPrintingDelayFlags],a + ld [wLetterPrintingDelayFlags], a ret .doTextCommand push hl - cp a,$17 - jp z,TextCommand17 - cp a,$0e - jp nc,TextCommand0B ; if a != 0x17 and a >= 0xE, go to command 0xB + cp a, $17 + jp z, TextCommand17 + cp a, $0e + jp nc, TextCommand0B ; if a != 0x17 and a >= 0xE, go to command 0xB ; if a < 0xE, use a jump table - ld hl,TextCommandJumpTable + ld hl, TextCommandJumpTable push bc add a - ld b,$00 - ld c,a - add hl,bc + ld b, $00 + ld c, a + add hl, bc pop bc - ld a,[hli] - ld h,[hl] - ld l,a + ld a, [hli] + ld h, [hl] + ld l, a jp [hl] ; draw box @@ -413,17 +409,17 @@ NextTextCommand:: ; CC = width TextCommand04:: pop hl - ld a,[hli] - ld e,a - ld a,[hli] - ld d,a - ld a,[hli] - ld b,a - ld a,[hli] - ld c,a + ld a, [hli] + ld e, a + ld a, [hli] + ld d, a + ld a, [hli] + ld b, a + ld a, [hli] + ld c, a push hl - ld h,d - ld l,e + ld h, d + ld l, e call TextBoxBorder pop hl jr NextTextCommand @@ -432,13 +428,13 @@ TextCommand04:: ; 00{string} TextCommand00:: pop hl - ld d,h - ld e,l - ld h,b - ld l,c + ld d, h + ld e, l + ld h, b + ld l, c call PlaceString - ld h,d - ld l,e + ld h, d + ld l, e inc hl jr NextTextCommand @@ -447,13 +443,13 @@ TextCommand00:: ; AAAA = address of string TextCommand01:: pop hl - ld a,[hli] - ld e,a - ld a,[hli] - ld d,a + ld a, [hli] + ld e, a + ld a, [hli] + ld d, a push hl - ld h,b - ld l,c + ld h, b + ld l, c call PlaceString pop hl jr NextTextCommand @@ -466,18 +462,18 @@ TextCommand01:: ; bits 5-7 = unknown flags TextCommand02:: pop hl - ld a,[hli] - ld e,a - ld a,[hli] - ld d,a - ld a,[hli] + ld a, [hli] + ld e, a + ld a, [hli] + ld d, a + ld a, [hli] push hl - ld h,b - ld l,c - ld c,a + ld h, b + ld l, c + ld c, a call PrintBCDNumber - ld b,h - ld c,l + ld b, h + ld c, l pop hl jr NextTextCommand @@ -486,12 +482,12 @@ TextCommand02:: ; AAAA = new destination address TextCommand03:: pop hl - ld a,[hli] - ld [wUnusedCC3A],a - ld c,a - ld a,[hli] - ld [wUnusedCC3B],a - ld b,a + ld a, [hli] + ld [wTextDestinationTileAddrBuffer], a + ld c, a + ld a, [hli] + ld [wTextDestinationTileAddrBuffer + 1], a + ld b, a jp NextTextCommand ; repoint destination to second line of dialogue text box @@ -506,15 +502,15 @@ TextCommand05:: ; 06 ; (no arguments) TextCommand06:: - ld a,[wLinkState] - cp a,LINK_STATE_BATTLING - jp z,TextCommand0D - ld a,$ee ; down arrow + ld a, [wLinkState] + cp a, LINK_STATE_BATTLING + jp z, TextCommand0D + ld a, $ee ; down arrow Coorda 18, 16 ; place down arrow in lower right corner of dialogue text box push bc call ManualTextScroll ; blink arrow and wait for A or B to be pressed pop bc - ld a," " + ld a, " " Coorda 18, 16 ; overwrite down arrow with blank space pop hl jp NextTextCommand @@ -523,10 +519,10 @@ TextCommand06:: ; 07 ; (no arguments) TextCommand07:: - ld a," " + ld a, " " Coorda 18, 16 ; place blank space in lower right corner of dialogue text box - call Next1B18 ; scroll up text - call Next1B18 + call ScrollTextUpOneLine ; scroll up text + call ScrollTextUpOneLine pop hl coord bc, 1, 16 ; address of second line of dialogue text box jp NextTextCommand @@ -535,7 +531,7 @@ TextCommand07:: ; 08{code} TextCommand08:: pop hl - ld de,NextTextCommand + ld de, NextTextCommand push de ; return address jp [hl] @@ -547,25 +543,25 @@ TextCommand08:: ; bits 4-7 = how long the number is in bytes TextCommand09:: pop hl - ld a,[hli] - ld e,a - ld a,[hli] - ld d,a - ld a,[hli] + ld a, [hli] + ld e, a + ld a, [hli] + ld d, a + ld a, [hli] push hl - ld h,b - ld l,c - ld b,a - and a,$0f - ld c,a - ld a,b - and a,$f0 + ld h, b + ld l, c + ld b, a + and a, $0f + ld c, a + ld a, b + and a, $f0 swap a - set BIT_LEFT_ALIGN,a - ld b,a + set BIT_LEFT_ALIGN, a + ld b, a call PrintNumber - ld b,h - ld c,l + ld b, h + ld c, l pop hl jp NextTextCommand @@ -575,10 +571,10 @@ TextCommand09:: TextCommand0A:: push bc call Joypad - ld a,[hJoyHeld] - and a,A_BUTTON | B_BUTTON - jr nz,.skipDelay - ld c,30 + ld a, [hJoyHeld] + and a, A_BUTTON | B_BUTTON + jr nz, .skipDelay + ld c, 30 call DelayFrames .skipDelay pop bc @@ -592,24 +588,24 @@ TextCommand0B:: pop hl push bc dec hl - ld a,[hli] - ld b,a ; b = command number that got us here + ld a, [hli] + ld b, a ; b = command number that got us here push hl - ld hl,TextCommandSounds + ld hl, TextCommandSounds .loop - ld a,[hli] + ld a, [hli] cp b - jr z,.matchFound + jr z, .matchFound inc hl jr .loop .matchFound - cp a,$14 - jr z,.pokemonCry - cp a,$15 - jr z,.pokemonCry - cp a,$16 - jr z,.pokemonCry - ld a,[hl] + cp a, $14 + jr z, .pokemonCry + cp a, $15 + jr z, .pokemonCry + cp a, $16 + jr z, .pokemonCry + ld a, [hl] call PlaySound call WaitForSoundToFinish pop hl @@ -617,7 +613,7 @@ TextCommand0B:: jp NextTextCommand .pokemonCry push de - ld a,[hl] + ld a, [hl] call PlayCry pop de pop hl @@ -626,43 +622,43 @@ TextCommand0B:: ; format: text command ID, sound ID or cry ID TextCommandSounds:: - db $0B,SFX_GET_ITEM_1 - db $12,SFX_CAUGHT_MON - db $0E,SFX_POKEDEX_RATING - db $0F,SFX_GET_ITEM_1 - db $10,SFX_GET_ITEM_2 - db $11,SFX_GET_KEY_ITEM - db $13,SFX_DEX_PAGE_ADDED - db $14,NIDORINA ; used in OakSpeech - db $15,PIDGEOT ; used in SaffronCityText12 - db $16,DEWGONG ; unused? + db $0B, SFX_GET_ITEM_1 + db $12, SFX_TURN_OFF_PC + db $0E, SFX_POKEDEX_RATING + db $0F, SFX_GET_ITEM_1 + db $10, SFX_GET_ITEM_2 + db $11, SFX_GET_KEY_ITEM + db $13, SFX_TRADE_MACHINE + db $14, PIKACHU ; used in OakSpeech + db $15, PIDGEOT ; used in SaffronCityText12 + db $16, DEWGONG ; unused? ; draw ellipses ; 0CAA ; AA = number of ellipses to draw TextCommand0C:: pop hl - ld a,[hli] - ld d,a + ld a, [hli] + ld d, a push hl - ld h,b - ld l,c + ld h, b + ld l, c .loop - ld a,$75 ; ellipsis - ld [hli],a + ld a, $75 ; ellipsis + ld [hli], a push de call Joypad pop de - ld a,[hJoyHeld] ; joypad state - and a,A_BUTTON | B_BUTTON - jr nz,.skipDelay ; if so, skip the delay - ld c,10 + ld a, [hJoyHeld] ; joypad state + and a, A_BUTTON | B_BUTTON + jr nz, .skipDelay ; if so, skip the delay + ld c, 10 call DelayFrames .skipDelay dec d - jr nz,.loop - ld b,h - ld c,l + jr nz, .loop + ld b, h + ld c, l pop hl jp NextTextCommand @@ -682,23 +678,23 @@ TextCommand0D:: ; BB = bank TextCommand17:: pop hl - ld a,[H_LOADEDROMBANK] + ld a, [H_LOADEDROMBANK] push af - ld a,[hli] - ld e,a - ld a,[hli] - ld d,a - ld a,[hli] - ld [H_LOADEDROMBANK],a - ld [MBC1RomBank],a + ld a, [hli] + ld e, a + ld a, [hli] + ld d, a + ld a, [hli] + ld [H_LOADEDROMBANK], a + ld [MBC1RomBank], a push hl - ld l,e - ld h,d + ld l, e + ld h, d call TextCommandProcessor pop hl pop af - ld [H_LOADEDROMBANK],a - ld [MBC1RomBank],a + ld [H_LOADEDROMBANK], a + ld [MBC1RomBank], a jp NextTextCommand TextCommandJumpTable:: diff --git a/home/vblank.asm b/home/vblank.asm index f69d4a86..9cc8d42f 100644 --- a/home/vblank.asm +++ b/home/vblank.asm @@ -5,6 +5,11 @@ VBlank:: push de push hl + ld a, [rVBK] ; vram bank + push af + xor a + ld [rVBK], a ; reset vram bank to 0 + ld a, [H_LOADEDROMBANK] ld [wVBlankSavedROMBank], a @@ -27,14 +32,16 @@ VBlank:: call VBlankCopyDouble call UpdateMovingBgTiles call $ff80 ; hOAMDMA - ld a, Bank(PrepareOAMData) + ld a, BANK(PrepareOAMData) ld [H_LOADEDROMBANK], a ld [MBC1RomBank], a call PrepareOAMData ; VBlank-sensitive operations end. + call TrackPlayTime ; keep track of time played call Random + call ReadJoypad ld a, [H_VBLANKOCCURRED] and a @@ -48,40 +55,22 @@ VBlank:: jr z, .skipDec dec a ld [H_FRAMECOUNTER], a - .skipDec + call FadeOutAudio - ld a, [wAudioROMBank] ; music ROM bank - ld [H_LOADEDROMBANK], a - ld [MBC1RomBank], a + callbs Music_DoLowHealthAlarm + callbs Audio1_UpdateMusic - cp BANK(Audio1_UpdateMusic) - jr nz, .checkForAudio2 -.audio1 - call Audio1_UpdateMusic - jr .afterMusic -.checkForAudio2 - cp BANK(Audio2_UpdateMusic) - jr nz, .audio3 -.audio2 - call Music_DoLowHealthAlarm - call Audio2_UpdateMusic - jr .afterMusic -.audio3 - call Audio3_UpdateMusic -.afterMusic - - callba TrackPlayTime ; keep track of time played - - ld a, [hDisableJoypadPolling] - and a - call z, ReadJoypad + call SerialFunction ld a, [wVBlankSavedROMBank] ld [H_LOADEDROMBANK], a ld [MBC1RomBank], a + pop af + ld [rVBK],a + pop hl pop de pop bc diff --git a/home/vcopy.asm b/home/vcopy.asm index b7fb099e..2974dfec 100644 --- a/home/vcopy.asm +++ b/home/vcopy.asm @@ -33,13 +33,13 @@ ClearBgMap:: jr nz,.loop ret -RedrawRowOrColumn:: ; This function redraws a BG row of height 2 or a BG column of width 2. ; One of its main uses is redrawing the row or column that will be exposed upon ; scrolling the BG when the player takes a step. Redrawing only the exposed ; row or column is more efficient than redrawing the entire screen. ; However, this function is also called repeatedly to redraw the whole screen ; when necessary. It is also used in trade animation and elevator code. +RedrawRowOrColumn:: ld a,[hRedrawRowOrColumnMode] and a ret z @@ -123,11 +123,7 @@ AutoBgMapTransfer:: ld a,[H_AUTOBGTRANSFERENABLED] and a ret z - ld hl,[sp + 0] - ld a,h - ld [H_SPTEMP],a - ld a,l - ld [H_SPTEMP + 1],a ; save stack pinter + ld [H_SPTEMP],sp ; save stack pinter ld a,[H_AUTOBGTRANSFERPORTION] and a jr z,.transferTopThird @@ -193,9 +189,9 @@ TransferBgRows:: jr nz, TransferBgRows ld a, [H_SPTEMP] - ld h, a - ld a, [H_SPTEMP + 1] ld l, a + ld a, [H_SPTEMP + 1] + ld h, a ld sp, hl ret @@ -205,11 +201,7 @@ VBlankCopyBgMap:: ld a,[H_VBCOPYBGSRC] ; doubles as enabling byte and a ret z - ld hl,[sp + 0] - ld a,h - ld [H_SPTEMP],a - ld a,l - ld [H_SPTEMP + 1],a ; save stack pointer + ld [H_SPTEMP],sp ; save stack pointer ld a,[H_VBCOPYBGSRC] ld l,a ld a,[H_VBCOPYBGSRC + 1] @@ -238,11 +230,7 @@ VBlankCopyDouble:: and a ret z - ld hl, [sp + 0] - ld a, h - ld [H_SPTEMP], a - ld a, l - ld [H_SPTEMP + 1], a + ld [H_SPTEMP],sp ; save stack pointer ld a, [H_VBCOPYDOUBLESRC] ld l, a @@ -285,21 +273,14 @@ VBlankCopyDouble:: dec b jr nz, .loop - ld a, l - ld [H_VBCOPYDOUBLEDEST], a - ld a, h - ld [H_VBCOPYDOUBLEDEST + 1], a - - ld hl, [sp + 0] - ld a, l - ld [H_VBCOPYDOUBLESRC], a - ld a, h - ld [H_VBCOPYDOUBLESRC + 1], a + ld [H_VBCOPYDOUBLESRC],sp + ld sp,hl ; load destination into sp to save time with ld [$xxxx],sp + ld [H_VBCOPYDOUBLEDEST], sp ld a, [H_SPTEMP] - ld h, a - ld a, [H_SPTEMP + 1] ld l, a + ld a, [H_SPTEMP + 1] + ld h, a ld sp, hl ret @@ -316,11 +297,7 @@ VBlankCopy:: and a ret z - ld hl, [sp + 0] - ld a, h - ld [H_SPTEMP], a - ld a, l - ld [H_SPTEMP + 1], a + ld [H_SPTEMP],sp ld a, [H_VBCOPYSRC] ld l, a @@ -355,21 +332,14 @@ VBlankCopy:: dec b jr nz, .loop - ld a, l - ld [H_VBCOPYDEST], a - ld a, h - ld [H_VBCOPYDEST + 1], a - - ld hl, [sp + 0] - ld a, l - ld [H_VBCOPYSRC], a - ld a, h - ld [H_VBCOPYSRC + 1], a + ld [H_VBCOPYSRC],sp + ld sp,hl + ld [H_VBCOPYDEST],sp ld a, [H_SPTEMP] - ld h, a - ld a, [H_SPTEMP + 1] ld l, a + ld a, [H_SPTEMP + 1] + ld h, a ld sp, hl ret @@ -383,6 +353,10 @@ UpdateMovingBgTiles:: and a ret z ; no animations if indoors (or if a menu set this to 0) + ld a,[rLY] + cp $90 ; check if not in vblank period??? (maybe if vblank is too long) + ret c + ld a, [hMovingBGTilesCounter1] inc a ld [hMovingBGTilesCounter1], a |