diff options
Diffstat (limited to 'home')
48 files changed, 1569 insertions, 1099 deletions
diff --git a/home/audio.asm b/home/audio.asm index eded85e9..41fb503a 100644 --- a/home/audio.asm +++ b/home/audio.asm @@ -24,6 +24,8 @@ PlayDefaultMusicCommon:: jr z, .walking cp $2 jr z, .surfing + call CheckForNoBikingMusicMap + jr c, .walking ld a, MUSIC_BIKE_RIDING jr .next @@ -66,33 +68,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_1F + jr z, .found + cp VICTORY_ROAD_2F + jr z, .found + cp VICTORY_ROAD_3F + jr z, .found + cp INDIGO_PLATEAU + jr z, .found + and a + ret +.found + scf + ret -.next +UpdateMusic6Times:: ld c, 6 +UpdateMusicCTimes:: .loop push bc push hl - call Bankswitch + farcall Audio1_UpdateMusic pop hl pop bc dec c @@ -135,7 +136,20 @@ PlayMusic:: ld [wAudioROMBank], a ld [wAudioSavedROMBank], a ld a, b + jr PlaySound +Func_2223:: + xor a + ld [wChannelSoundIDs + Ch5], a + ld [wChannelSoundIDs + Ch6], a + ld [wChannelSoundIDs + Ch7], a + ld [wChannelSoundIDs + Ch8], a + ldh [rNR10], a + ret + +StopAllMusic:: + ld a, SFX_STOP_ALL_MUSIC + ld [wNewSoundID], a ; plays music specified by a. If value is $ff, music is stopped PlaySound:: push hl @@ -168,47 +182,116 @@ PlaySound:: .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:: ldh a, [hLoadedROMBank] - ldh [hSavedROMBank], a + push af ld a, [wAudioROMBank] - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a + 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 + pop bc + pop de + pop hl + ret + +InitSFXVariables:: + push hl + push de + push bc + homecall Audio2_InitSFXVariables + pop bc + pop de + pop hl + ret + +StopAllAudio:: + push hl + push de + push bc + homecall Audio2_StopAllAudio + pop bc + pop de + pop hl + ret + +DetermineAudioFunction:: + ldh a, [hLoadedROMBank] + push af + ld a, [wAudioROMBank] + call BankswitchCommon +; determine the audio function, based on the bank cp BANK(Audio1_PlaySound) jr nz, .checkForAudio2 ; audio 1 ld a, b call Audio1_PlaySound - jr .next2 + jr .done .checkForAudio2 cp BANK(Audio2_PlaySound) - jr nz, .audio3 + jr nz, .checkForAudio3 ; audio 2 ld a, b call Audio2_PlaySound - jr .next2 + jr .done -.audio3 +.checkForAudio3 + cp BANK(Audio3_PlaySound) + jr nz, .audio4 +; audio 3 ld a, b call Audio3_PlaySound - -.next2 - ldh a, [hSavedROMBank] - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a jr .done -.fadeOut +.audio4 +; invalid banks will default to audio 4 +; 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/bankswitch.asm b/home/bankswitch.asm index 52c8a45c..3e85e955 100644 --- a/home/bankswitch.asm +++ b/home/bankswitch.asm @@ -5,31 +5,11 @@ BankswitchHome:: ldh a, [hLoadedROMBank] ld [wBankswitchHomeSavedROMBank], a ld a, [wBankswitchHomeTemp] - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a + call BankswitchCommon ret BankswitchBack:: ; returns from BankswitchHome ld a, [wBankswitchHomeSavedROMBank] - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a - ret - -Bankswitch:: -; self-contained bankswitch, use this when not in the home bank -; switches to the bank in b - ldh a, [hLoadedROMBank] - push af - ld a, b - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a - ld bc, .Return - push bc - jp hl -.Return - pop bc - ld a, b - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a + call BankswitchCommon ret diff --git a/home/bankswitch2.asm b/home/bankswitch2.asm new file mode 100644 index 00000000..cc7169cd --- /dev/null +++ b/home/bankswitch2.asm @@ -0,0 +1,39 @@ +BankswitchCommon:: + ldh [hLoadedROMBank], a + ld [MBC1RomBank], a + ret + +Bankswitch:: +; self-contained bankswitch, use this when not in the home bank +; switches to the bank in b + ldh a, [hLoadedROMBank] + push af + ld a, b + ldh [hLoadedROMBank], a + ld [MBC1RomBank], a + call JumpToAddress + pop bc + ld a, b + ldh [hLoadedROMBank], a + ld [MBC1RomBank], a + ret +JumpToAddress:: + jp hl + +SwitchSRAMBankAndLatchClockData:: + push af + ld a, $1 + ld [MBC1SRamBankingMode], a + ld a, SRAM_ENABLE + ld [MBC1SRamEnable], a + pop af + ld [MBC1SRamBank], a + ret + +PrepareRTCDataAndDisableSRAM:: + push af + ld a, $0 + ld [MBC1SRamBankingMode], a + ld [MBC1SRamEnable], a + pop af + ret diff --git a/home/cgb_palettes.asm b/home/cgb_palettes.asm new file mode 100644 index 00000000..b8cc92c6 --- /dev/null +++ b/home/cgb_palettes.asm @@ -0,0 +1,85 @@ +UpdateGBCPal_BGP:: + push af + ldh a, [hGBC] + and a + jr z, .notGBC + push bc + push de + push hl + ldh a, [rBGP] + ld b, a + ld a, [wLastBGP] + cp b + jr z, .noChangeInBGP + farcall _UpdateGBCPal_BGP +.noChangeInBGP + pop hl + pop de + pop bc +.notGBC + pop af + ret + +UpdateGBCPal_OBP0:: + push af + ldh a, [hGBC] + and a + jr z, .notGBC + push bc + push de + push hl + ldh a, [rOBP0] + ld b, a + ld a, [wLastOBP0] + cp b + jr z, .noChangeInOBP0 + ld b, BANK(_UpdateGBCPal_OBP) + ld hl, _UpdateGBCPal_OBP + ld c, CONVERT_OBP0 + call Bankswitch +.noChangeInOBP0 + pop hl + pop de + pop bc +.notGBC + pop af + ret + +UpdateGBCPal_OBP1:: + push af + ldh a, [hGBC] + and a + jr z, .notGBC + push bc + push de + push hl + ldh a, [rOBP1] + ld b, a + ld a, [wLastOBP1] + cp b + jr z, .noChangeInOBP1 + ld b, BANK(_UpdateGBCPal_OBP) + ld hl, _UpdateGBCPal_OBP + ld c, CONVERT_OBP1 + call Bankswitch +.noChangeInOBP1 + pop hl + pop de + pop bc +.notGBC + pop af + ret + +Func_3082:: + ldh a, [hLoadedROMBank] + push af + call FadeOutAudio + ld a, BANK(Music_DoLowHealthAlarm) + call BankswitchCommon + call Music_DoLowHealthAlarm + ld a, BANK(Audio1_UpdateMusic) + call BankswitchCommon + call Audio1_UpdateMusic + pop af + call BankswitchCommon + ret diff --git a/home/copy.asm b/home/copy.asm index 880d1fb7..b239d951 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 ldh a, [hLoadedROMBank] push af - ld a, [wBuffer] - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a + ld a, [wFarCopyDataSavedROMBank] + call BankswitchCommon call CopyData pop af - ldh [hLoadedROMBank], 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 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:: + ldh 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:: + ldh 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 1c9a56f3..6245ad5d 100644 --- a/home/copy2.asm +++ b/home/copy2.asm @@ -1,62 +1,41 @@ -FarCopyData2:: -; Identical to FarCopyData, but uses hROMBankTemp -; as temp space instead of wBuffer. - ldh [hROMBankTemp], a - ldh a, [hLoadedROMBank] - push af - ldh a, [hROMBankTemp] - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a - call CopyData - pop af - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a - ret - -FarCopyData3:: -; Copy bc bytes from a:de to hl. - ldh [hROMBankTemp], a - ldh a, [hLoadedROMBank] - push af - ldh a, [hROMBankTemp] - ldh [hLoadedROMBank], 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 - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a +IsTilePassable:: +; sets carry if tile is passable, resets carry otherwise + homecall_sf _IsTilePassable ret FarCopyDataDouble:: ; Expand bc bytes of 1bpp image data -; from a:hl to 2bpp data at de. - ldh [hROMBankTemp], a +; from a:de to 2bpp data at hl. + ld [wFarCopyDataSavedROMBank], a ldh a, [hLoadedROMBank] push af - ldh a, [hROMBankTemp] - ldh [hLoadedROMBank], 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 - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a + call BankswitchCommon ret CopyVideoData:: @@ -70,11 +49,10 @@ CopyVideoData:: ldh [hAutoBGTransferEnabled], a ldh a, [hLoadedROMBank] - ldh [hROMBankTemp], a + push af ld a, b - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a + call BankswitchCommon ld a, e ldh [hVBlankCopySource], a @@ -94,9 +72,8 @@ CopyVideoData:: .done ldh [hVBlankCopySize], a call DelayFrame - ldh a, [hROMBankTemp] - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a + pop af + call BankswitchCommon pop af ldh [hAutoBGTransferEnabled], a ret @@ -119,11 +96,10 @@ CopyVideoDataDouble:: xor a ; disable auto-transfer while copying ldh [hAutoBGTransferEnabled], a ldh a, [hLoadedROMBank] - ldh [hROMBankTemp], a + push af ld a, b - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a + call BankswitchCommon ld a, e ldh [hVBlankCopyDoubleSource], a @@ -143,9 +119,8 @@ CopyVideoDataDouble:: .done ldh [hVBlankCopyDoubleSize], a call DelayFrame - ldh a, [hROMBankTemp] - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a + pop af + call BankswitchCommon pop af ldh [hAutoBGTransferEnabled], a ret @@ -159,6 +134,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 + ldh a, [hLoadedROMBank] + 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/delay.asm b/home/delay.asm index 850b23e9..eba865c2 100644 --- a/home/delay.asm +++ b/home/delay.asm @@ -26,6 +26,7 @@ WaitForSoundToFinish:: inc hl inc hl or [hl] + and a jr nz, .waitLoop pop hl ret diff --git a/home/fade.asm b/home/fade.asm index f5ddf964..f38878b1 100644 --- a/home/fade.asm +++ b/home/fade.asm @@ -16,6 +16,9 @@ LoadGBPal:: ldh [rOBP0], a ld a, [hli] ldh [rOBP1], a + call UpdateGBCPal_BGP + call UpdateGBCPal_OBP0 + call UpdateGBCPal_OBP1 ret GBFadeInFromBlack:: @@ -34,6 +37,9 @@ GBFadeIncCommon: ldh [rOBP0], a ld a, [hli] ldh [rOBP1], a + call UpdateGBCPal_BGP + call UpdateGBCPal_OBP0 + call UpdateGBCPal_OBP1 ld c, 8 call DelayFrames dec b @@ -56,6 +62,9 @@ GBFadeDecCommon: ldh [rOBP0], a ld a, [hld] ldh [rBGP], a + call UpdateGBCPal_BGP + call UpdateGBCPal_OBP0 + call UpdateGBCPal_OBP1 ld c, 8 call DelayFrames dec b diff --git a/home/fade_audio.asm b/home/fade_audio.asm index 4ad2607d..f4e77c3f 100644 --- a/home/fade_audio.asm +++ b/home/fade_audio.asm @@ -38,9 +38,7 @@ FadeOutAudio:: ld b, a xor a ld [wAudioFadeOutControl], a - ld a, SFX_STOP_ALL_MUSIC - ld [wNewSoundID], a - call PlaySound + call StopAllMusic ld a, [wAudioSavedROMBank] ld [wAudioROMBank], a ld a, b diff --git a/home/header.asm b/home/header.asm index c12a0565..671f29b1 100644 --- a/home/header.asm +++ b/home/header.asm @@ -49,7 +49,7 @@ SECTION "vblank", ROM0[$0040] ds $48 - @, 0 ; unused SECTION "lcd", ROM0[$0048] - rst $38 + jp LCDC ds $50 - @, 0 ; unused diff --git a/home/hidden_objects.asm b/home/hidden_objects.asm index eccf1c8f..0003022b 100644 --- a/home/hidden_objects.asm +++ b/home/hidden_objects.asm @@ -1,5 +1,6 @@ UpdateCinnabarGymGateTileBlocks:: - farjp UpdateCinnabarGymGateTileBlocks_ + farcall UpdateCinnabarGymGateTileBlocks_ + ret CheckForHiddenObjectOrBookshelfOrCardKeyDoor:: ldh a, [hLoadedROMBank] @@ -9,22 +10,20 @@ CheckForHiddenObjectOrBookshelfOrCardKeyDoor:: jr z, .nothingFound ; A button is pressed ld a, BANK(CheckForHiddenObject) - ld [MBC1RomBank], a - ldh [hLoadedROMBank], a + call BankswitchCommon call CheckForHiddenObject ldh a, [hDidntFindAnyHiddenObject] and a jr nz, .hiddenObjectNotFound - ld a, [wHiddenObjectFunctionRomBank] - ld [MBC1RomBank], a - ldh [hLoadedROMBank], a - ld de, .returnAddress - push de - jp hl -.returnAddress xor a + ldh [hItemAlreadyFound], a + ld a, [wHiddenObjectFunctionRomBank] + call BankswitchCommon + call JumpToAddress + ldh a, [hItemAlreadyFound] jr .done .hiddenObjectNotFound + predef GetTileAndCoordsInFrontOfPlayer farcall PrintBookshelfText ldh a, [hFFDB] and a @@ -34,6 +33,5 @@ CheckForHiddenObjectOrBookshelfOrCardKeyDoor:: .done ldh [hItemAlreadyFound], a pop af - ld [MBC1RomBank], a - ldh [hLoadedROMBank], a + call BankswitchCommon ret diff --git a/home/init.asm b/home/init.asm index e5840e65..bb70615d 100644 --- a/home/init.asm +++ b/home/init.asm @@ -54,7 +54,7 @@ rLCDC_DEFAULT EQU %11100011 call ClearVram ld hl, HRAM_Begin - ld bc, HRAM_End - HRAM_Begin + ld bc, HRAM_End - HRAM_Begin - 1 call FillMemory call ClearSprites @@ -70,6 +70,8 @@ rLCDC_DEFAULT EQU %11100011 ldh [hSCX], a ldh [hSCY], a ldh [rIF], a + ld [wc0f3], a + ld [wc0f4], a ld a, 1 << VBLANK + 1 << TIMER + 1 << SERIAL ldh [rIE], a @@ -133,5 +135,4 @@ StopAllSounds:: ld [wAudioFadeOutControl], a ld [wNewSoundID], a ld [wLastMusicSoundID], a - dec a - jp PlaySound + jp StopAllMusic diff --git a/home/item_price.asm b/home/item_price.asm index 98eb31b1..39749ee9 100644 --- a/home/item_price.asm +++ b/home/item_price.asm @@ -9,8 +9,7 @@ GetItemPrice:: jr nz, .ok ld a, $f ; hardcoded Bank .ok - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a + call BankswitchCommon ld hl, wItemPrices ld a, [hli] ld h, [hl] @@ -33,12 +32,10 @@ GetItemPrice:: jr .done .getTMPrice ld a, BANK(GetMachinePrice) - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a + call BankswitchCommon call GetMachinePrice .done ld de, hItemPrice pop af - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a + call BankswitchCommon ret diff --git a/home/joypad.asm b/home/joypad.asm index 9bc8663e..5eb2962f 100644 --- a/home/joypad.asm +++ b/home/joypad.asm @@ -1,39 +1,5 @@ -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 - - ldh [rJOYP], a -REPT 6 - ldh a, [rJOYP] -ENDR - cpl - and %1111 - swap a - ld b, a - - ld a, 1 << 4 ; select button keys - ldh [rJOYP], a -REPT 10 - ldh a, [rJOYP] -ENDR - cpl - and %1111 - or b - - ldh [hJoyInput], a - - ld a, 1 << 4 + 1 << 5 ; deselect keys - ldh [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 + homejp _Joypad + +ReadJoypad:: + homejp ReadJoypad_ diff --git a/home/joypad2.asm b/home/joypad2.asm index 139dd3f5..30f9f788 100644 --- a/home/joypad2.asm +++ b/home/joypad2.asm @@ -66,7 +66,11 @@ WaitForTextScrollButtonPress:: ld a, [wTownMapSpriteBlinkingEnabled] and a jr z, .skipAnimation - call TownMapSpriteBlinkingAnimation + push de + push bc + callfar TownMapSpriteBlinkingAnimation + pop bc + pop de .skipAnimation hlcoord 18, 16 call HandleDownArrowBlinkTiming @@ -88,6 +92,7 @@ ManualTextScroll:: cp LINK_STATE_BATTLING jr z, .inLinkBattle call WaitForTextScrollButtonPress + call WaitForSoundToFinish ld a, SFX_PRESS_AB jp PlaySound .inLinkBattle diff --git a/home/lcdc.asm b/home/lcdc.asm new file mode 100644 index 00000000..4b350cc2 --- /dev/null +++ b/home/lcdc.asm @@ -0,0 +1,20 @@ +LCDC:: + push af + ldh a, [hLCDCPointer] ; doubles as enabling byte + and a + jr z, .noLCDCInterrupt + push hl + ; [C700 + [rLY]] --> [FF00 + [hLCDCPointer]] + ldh a, [rLY] + ld l, a + ld h, HIGH(wLYOverrides) + ld h, [hl] ; h != not part of pointer + ldh a, [hLCDCPointer] + ld l, a + ld a, h + ld h, $ff + ld [hl], a + pop hl +.noLCDCInterrupt + pop af + reti diff --git a/home/list_menu.asm b/home/list_menu.asm index c856e91d..f0480460 100644 --- a/home/list_menu.asm +++ b/home/list_menu.asm @@ -68,7 +68,7 @@ DisplayListMenuIDLoop:: .oldManBattle ld a, "▶" ldcoord_a 5, 4 ; place menu cursor in front of first menu entry - ld c, 80 + ld c, 20 call DelayFrames xor a ld [wCurrentMenuItem], a @@ -195,15 +195,13 @@ DisplayListMenuIDLoop:: DisplayChooseQuantityMenu:: ; text box dimensions/coordinates for just quantity hlcoord 15, 9 - ld b, 1 ; height - ld c, 3 ; width + lb bc, 1, 3 ; height and width ld a, [wListMenuID] cp PRICEDITEMLISTMENU jr nz, .drawTextBox ; text box dimensions/coordinates for quantity and price hlcoord 7, 9 - ld b, 1 ; height - ld c, 11 ; width + lb bc, 1, 11 ; height and width .drawTextBox call TextBoxBorder hlcoord 16, 10 @@ -335,8 +333,7 @@ ExitListMenu:: PrintListMenuEntries:: hlcoord 5, 3 - ld b, 9 - ld c, 14 + lb bc, 9, 14 call ClearScreenArea ld a, [wListPointer] ld e, a @@ -351,7 +348,7 @@ PrintListMenuEntries:: jr nz, .skipMultiplying ; if it's an item menu ; item entries are 2 bytes long, so multiply by 2 - sla a + add a sla c .skipMultiplying add e @@ -500,7 +497,7 @@ PrintListMenuEntries:: ld a, [wMenuItemToSwap] ; ID of item chosen for swapping (counts from 1) and a ; is an item being swapped? jr z, .nextListEntry - sla a + add a cp c ; is it this item? jr nz, .nextListEntry dec hl diff --git a/home/load_font.asm b/home/load_font.asm index 3b56d3a8..8ed0f0a7 100644 --- a/home/load_font.asm +++ b/home/load_font.asm @@ -23,7 +23,7 @@ LoadTextBoxTilePatterns:: ld de, vChars2 tile $60 ld bc, TextBoxGraphicsEnd - TextBoxGraphics ld a, BANK(TextBoxGraphics) - jp FarCopyData2 ; if LCD is off, transfer all at once + jp FarCopyData ; if LCD is off, transfer all at once .on ld de, TextBoxGraphics ld hl, vChars2 tile $60 @@ -39,7 +39,7 @@ LoadHpBarAndStatusTilePatterns:: ld de, vChars2 tile $62 ld bc, HpBarAndStatusGraphicsEnd - HpBarAndStatusGraphics ld a, BANK(HpBarAndStatusGraphics) - jp FarCopyData2 ; if LCD is off, transfer all at once + jp FarCopyData ; if LCD is off, transfer all at once .on ld de, HpBarAndStatusGraphics ld hl, vChars2 tile $62 diff --git a/home/map_objects.asm b/home/map_objects.asm index 27a69965..a54e8f31 100644 --- a/home/map_objects.asm +++ b/home/map_objects.asm @@ -70,6 +70,60 @@ IsItemInBag:: and a ret +IsSurfingPikachuInParty:: +; set bit 6 of wd472 if true +; also calls Func_3467, which is a bankswitch to IsStarterPikachuInOurParty + ld a, [wd472] + and $3f + ld [wd472], a + ld hl, wPartyMon1 + ld c, PARTY_LENGTH + ld b, SURF +.loop + ld a, [hl] + cp STARTER_PIKACHU + jr nz, .notPikachu + push hl + ld de, $8 + add hl, de + ld a, [hli] + cp b ; does pikachu have surf as one of its moves + jr z, .hasSurf + ld a, [hli] + cp b + jr z, .hasSurf + ld a, [hli] + cp b + jr z, .hasSurf + ld a, [hli] + cp b + jr nz, .noSurf +.hasSurf + ld a, [wd472] + set 6, a + ld [wd472], a +.noSurf + pop hl +.notPikachu + ld de, wPartyMon2 - wPartyMon1 + add hl, de + dec c + jr nz, .loop + call Func_3467 + ret + +Func_3467:: + push hl + push bc + callfar IsStarterPikachuInOurParty + pop bc + pop hl + ret nc + ld a, [wd472] + set 7, a + ld [wd472], a + ret + DisplayPokedex:: ld [wd11e], a farjp _DisplayPokedex @@ -93,6 +147,26 @@ SetSpriteImageIndexAfterSettingFacingDirection:: ld [hl], a ret +SpriteFunc_34a1:: + ldh a, [hSpriteIndex] + swap a + add $e + ld l, a + ld h, $c2 + ld c, [hl] + dec c + swap c + ldh a, [hSpriteOffset] + add c + ld c, a + ldh a, [hSpriteHeight] + swap a + add $2 + ld l, a + dec h + ld [hl], c + ret + ; tests if the player's coordinates are in a specified array ; INPUT: ; hl = address of array @@ -241,8 +315,8 @@ GetSpriteMovementByte2Pointer:: ldh a, [hSpriteIndex] dec a add a - ld d, 0 ld e, a + ld d, 0 add hl, de pop de ret diff --git a/home/names2.asm b/home/names2.asm index 7b905fc5..b0be05df 100644 --- a/home/names2.asm +++ b/home/names2.asm @@ -47,8 +47,7 @@ GetName:: .otherEntries ; 2-7 = other names ld a, [wPredefBank] - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a + call BankswitchCommon ld a, [wNameListType] dec a add a @@ -95,6 +94,5 @@ GetName:: pop bc pop hl pop af - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a + call BankswitchCommon ret diff --git a/home/npc_movement.asm b/home/npc_movement.asm index a3367f9a..40942bf3 100644 --- a/home/npc_movement.asm +++ b/home/npc_movement.asm @@ -31,13 +31,11 @@ RunNPCMovementScript:: ldh a, [hLoadedROMBank] push af ld a, [wNPCMovementScriptBank] - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a + call BankswitchCommon ld a, [wNPCMovementScriptFunctionNum] call CallFunctionInTable pop af - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a + call BankswitchCommon ret .NPCMovementScriptPointerTables @@ -52,13 +50,11 @@ EndNPCMovementScript:: DebugPressedOrHeldB:: IF DEF(_DEBUG) - ld a, [wd732] - bit 1, a - ret z ldh a, [hJoyHeld] bit BIT_B_BUTTON, a ret nz ldh a, [hJoyPressed] bit BIT_B_BUTTON, a + ret ENDC ret diff --git a/home/overworld.asm b/home/overworld.asm index eb6f2ddb..50edcf74 100644 --- a/home/overworld.asm +++ b/home/overworld.asm @@ -1,8 +1,3 @@ -HandleMidJump:: -; Handle the player jumping down -; a ledge in the overworld. - farjp _HandleMidJump - EnterMap:: ; Load a new map. ld a, $ff @@ -24,11 +19,18 @@ EnterMap:: ld a, [hl] and 1 << 4 | 1 << 3 ; fly warp or dungeon warp jr z, .didNotEnterUsingFlyWarpOrDungeonWarp - res 3, [hl] farcall EnterMapAnim call UpdateSprites + ld hl, wd732 + res 3, [hl] + ld hl, wd72e + res 4, [hl] .didNotEnterUsingFlyWarpOrDungeonWarp + call IsSurfingPikachuInParty farcall 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,10 +44,9 @@ OverworldLoop:: call DelayFrame OverworldLoopLessDelay:: call DelayFrame + call IsSurfingPikachuInParty call LoadGBPal - ld a, [wd736] - bit 6, a ; jumping down a ledge? - call nz, HandleMidJump + call HandleMidJump ld a, [wWalkCounter] and a jp nz, .moveAhead ; if the player sprite has not yet completed the walking animation @@ -91,7 +92,10 @@ OverworldLoopLessDelay:: ldh a, [hItemAlreadyFound] and a jp z, OverworldLoop ; jump if a hidden object or bookshelf was found, but not if a card key door was found + xor a + ld [wd436], a ; new yellow address call IsSpriteOrSignInFrontOfPlayer + call Func_0ffe ldh a, [hSpriteIndexOrTextID] and a jp z, OverworldLoop @@ -109,39 +113,31 @@ OverworldLoopLessDelay:: ld a, [wEnteringCableClub] and a jr z, .checkForOpponent - dec a - ld a, 0 - ld [wEnteringCableClub], a - jr z, .changeMap -; XXX can this code be reached? - predef LoadSAV - ld a, [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 + xor a + ld [wLinkTimeoutCounter], a jp EnterMap .checkForOpponent ld a, [wCurOpponent] and a jp nz, .newBattle jp OverworldLoop + .noDirectionButtonsPressed + call UpdateSprites ld hl, wFlags_0xcd60 res 2, [hl] - call UpdateSprites + xor a + ld [wd435], a ld a, 1 ld [wCheckFor180DegreeTurn], a ld a, [wPlayerMovingDirection] ; the direction that was pressed last time and a - jp z, OverworldLoop + jr z, .overworldloop ; if a direction was pressed last time ld [wPlayerLastStopDirection], a ; save the last direction xor a ld [wPlayerMovingDirection], a ; zero the direction +.overworldloop jp OverworldLoop .checkIfDownButtonIsPressed @@ -174,7 +170,7 @@ OverworldLoopLessDelay:: jr z, .noDirectionButtonsPressed ld a, 1 ld [wSpritePlayerStateData1XStepVector], a - + ld a, 1 .handleDirectionButtonPress ld [wPlayerDirection], a ; new direction @@ -189,44 +185,13 @@ OverworldLoopLessDelay:: ld a, [wPlayerLastStopDirection] ; old direction cp b jr z, .noDirectionChange -; Check whether the player did a 180-degree turn. -; It appears that this code was supposed to show the player rotate by having -; the player's sprite face an intermediate direction before facing the opposite -; direction (instead of doing an instantaneous about-face), but the intermediate -; direction is only set for a short period of time. It is unlikely for it to -; ever be visible because DelayFrame is called at the start of OverworldLoop and -; normally not enough cycles would be executed between then and the time the -; direction is set for V-blank to occur while the direction is still set. - swap a ; put old direction in upper half - or b ; put new direction in lower half - cp (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 (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 (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 (PLAYER_DIR_LEFT << 4) | PLAYER_DIR_RIGHT ; change dir from left to right - jr nz, .holdIntermediateDirectionLoop - ld a, PLAYER_DIR_UP - ld [wPlayerMovingDirection], a -.holdIntermediateDirectionLoop + ld a, $8 + ld [wd435], a +; unlike in red/blue, yellow does not have the 180 degrees odd code ld hl, wFlags_0xcd60 set 2, [hl] - ld hl, wCheckFor180DegreeTurn - dec [hl] - jr nz, .holdIntermediateDirectionLoop + xor a + ld [wCheckFor180DegreeTurn], a ld a, [wPlayerDirection] ld [wPlayerMovingDirection], a call NewBattle @@ -263,48 +228,26 @@ OverworldLoopLessDelay:: .noCollision ld a, $08 ld [wWalkCounter], a + callfar Func_fcc08 jr .moveAhead2 .moveAhead - ld a, [wd736] - bit 7, a - jr z, .noSpinning - farcall LoadSpinnerArrowTiles -.noSpinning + call IsSpinning call UpdateSprites .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 + xor a + ld [wd435], a call DoBikeSpeedup -.normalPlayerSpriteAdvancement call AdvancePlayerSprite ld a, [wWalkCounter] and a jp nz, CheckMapConnections ; it seems like this check will never succeed (the other place where CheckMapConnections is run works) ; walking animation finished - ld a, [wd730] - bit 7, a - jr nz, .doneStepCounting ; if button presses are being simulated, don't count steps -; step counting - ld hl, wStepCounter - dec [hl] - ld a, [wd72c] - bit 0, a - jr z, .doneStepCounting - ld hl, wNumberOfNoRandomBattleStepsLeft - dec [hl] - jr nz, .doneStepCounting - ld hl, wd72c - res 0, [hl] ; indicate that the player has stepped thrice since the last battle -.doneStepCounting - CheckEvent EVENT_IN_SAFARI_ZONE + call StepCountCheck + CheckEvent EVENT_IN_SAFARI_ZONE ; in the safari zone? jr z, .notSafariZone farcall SafariZoneCheckSteps ld a, [wSafariZoneGameOver] @@ -346,12 +289,31 @@ OverworldLoopLessDelay:: callfar AnyPartyAlive ld a, d and a - jr z, .allPokemonFainted + jr z, AllPokemonFainted .noFaintCheck ld c, 10 call DelayFrames jp EnterMap -.allPokemonFainted + +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 @@ -375,6 +337,12 @@ NewBattle:: ; function to make bikes twice as fast as walking 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 @@ -385,15 +353,16 @@ DoBikeSpeedup:: 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] and a jp z, CheckMapConnections - ld a, [wNumberOfWarps] ld b, 0 + ld a, [wNumberOfWarps] ld c, a ld a, [wYCoord] ld d, a @@ -436,6 +405,17 @@ CheckWarpsNoCollisionLoop:: 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] @@ -466,13 +446,6 @@ CheckWarpsCollision:: jr nz, .loop jp OverworldLoop -CheckWarpsNoCollisionRetry1:: - inc hl -CheckWarpsNoCollisionRetry2:: - inc hl - inc hl - jp ContinueCheckWarpsNoCollisionLoop - WarpFound1:: ld a, [hli] ld [wDestinationWarpID], a @@ -500,6 +473,7 @@ WarpFound2:: ld [wMapPalOffset], a call GBFadeOutToBlack .notRockTunnel + callfar SetPikachuSpawnOutside call PlayMapChangeSound jr .done @@ -516,9 +490,9 @@ WarpFound2:: dec a ; is the player on a warp pad? jr nz, .notWarpPad ; if the player is on a warp pad + call LeaveMapAnim ld hl, wd732 set 3, [hl] - call LeaveMapAnim jr .skipMapChangeSound .notWarpPad call PlayMapChangeSound @@ -526,8 +500,11 @@ WarpFound2:: ld hl, wd736 res 0, [hl] res 1, [hl] + callfar SetPikachuSpawnWarpPad jr .done + .goBackOutside + callfar SetPikachuSpawnBackOutside ld a, [wLastMap] ld [wCurMap], a call PlayMapChangeSound @@ -539,11 +516,6 @@ WarpFound2:: 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 @@ -673,13 +645,17 @@ CheckMapConnections:: ld a, h ld [wCurrentTileBlockMapViewPointer + 1], a .loadNewMap ; load the connected map that was entered + ld hl, wPikachuOverworldStateFlags + set 4, [hl] + ld a, $2 + ld [wPikachuSpawnState], a call LoadMapHeader call PlayDefaultMusicFadeOutCurrent ld b, SET_PAL_OVERWORLD call RunPaletteCommand ; Since the sprite set shouldn't change, this will just update VRAM slots at ; x#SPRITESTATEDATA2_IMAGEBASEOFFSET without loading any tile patterns. - farcall InitMapSprites + call InitMapSprites call LoadTileBlockMap jp OverworldLoopLessDelay @@ -688,6 +664,11 @@ CheckMapConnections:: ; function to play a sound when changing maps PlayMapChangeSound:: + ld a, [wCurMapTileset] + cp FACILITY + jr z, .didNotGoThroughDoor + cp CEMETERY + jr z, .didNotGoThroughDoor lda_coord 8, 8 ; upper left tile of the 4x4 square the player's sprite is standing on cp $0b ; door tile in tileset 0 jr nz, .didNotGoThroughDoor @@ -762,19 +743,16 @@ HandleBlackOut:: call StopMusic ld hl, wd72e res 5, [hl] - ld a, BANK(ResetStatusAndHalveMoneyOnBlackout) ; also BANK(SpecialWarpIn) and BANK(SpecialEnterMap) - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a - call ResetStatusAndHalveMoneyOnBlackout + ld a, BANK(SpecialWarpIn) ; also BANK(SpecialEnterMap) + call BankswitchCommon + callfar ResetStatusAndHalveMoneyOnBlackout call SpecialWarpIn call PlayDefaultMusicFadeOutCurrent jp SpecialEnterMap StopMusic:: ld [wAudioFadeOutControl], a - ld a, SFX_STOP_ALL_MUSIC - ld [wNewSoundID], a - call PlaySound + call StopAllMusic .wait ld a, [wAudioFadeOutControl] and a @@ -786,22 +764,33 @@ 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 + call Func_07c4 ld a, BANK(SpecialWarpIn) - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a + call BankswitchCommon call SpecialWarpIn jp SpecialEnterMap LeaveMapAnim:: farjp _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. @@ -837,7 +826,7 @@ LoadPlayerSpriteGraphics:: dec a jp z, LoadBikePlayerSpriteGraphics dec a - jp z, LoadSurfingPlayerSpriteGraphics + jp z, LoadSurfingPlayerSpriteGraphics2 jp LoadWalkingPlayerSpriteGraphics IsBikeRidingAllowed:: @@ -878,23 +867,16 @@ LoadTilesetTilePatternData:: ld de, vTileset ld bc, $600 ld a, [wTilesetBank] - jp FarCopyData2 + jp FarCopyData ; this loads the current maps complete tile map (which references blocks, not individual tiles) to C6E8 ; it can also load partial tile maps of connected maps into a border of length 3 around the current map LoadTileBlockMap:: ; fill C6E8-CBFB with the background tile ld hl, wOverworldMap - ld a, [wMapBackgroundTile] - ld d, a ld bc, wOverworldMapEnd - wOverworldMap -.backgroundTileLoop - ld a, d - ld [hli], a - dec bc - ld a, c - or b - jr nz, .backgroundTileLoop + 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 @@ -1073,8 +1055,7 @@ 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 ldh [hSpriteIndexOrTextID], a @@ -1083,39 +1064,10 @@ IsSpriteOrSignInFrontOfPlayer:: 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] - ldh [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 @@ -1127,8 +1079,7 @@ IsSpriteOrSignInFrontOfPlayer:: dec b jr nz, .counterTilesLoop -; part of the above function, but sometimes its called on its own, when signs are irrelevant -; the caller must zero [hSpriteIndexOrTextID] +; 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) IsSpriteInFrontOfPlayer2:: @@ -1172,13 +1123,10 @@ IsSpriteInFrontOfPlayer2:: 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, wSprite01StateData1 - ld d, a +; yellow does not have the "if sprites are existant" check ld e, $01 + ld d, $f .spriteLoop push hl ld a, [hli] ; image (0 if no sprite) @@ -1204,7 +1152,9 @@ IsSpriteInFrontOfPlayer2:: inc e dec d jr nz, .spriteLoop + xor a ret + .foundSpriteInFrontOfPlayer pop hl ld a, l @@ -1214,6 +1164,52 @@ IsSpriteInFrontOfPlayer2:: set 7, [hl] ; set flag to make the sprite face the player ld a, e ldh [hSpriteIndexOrTextID], a + ldh 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] + ldh [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) @@ -1230,14 +1226,31 @@ CollisionCheckOnLand:: ld d, a ld a, [wSpritePlayerStateData1CollisionData] and d ; check if a sprite is in the direction the player is trying to go + nop ; ??? why is this in the code jr nz, .collision xor a ldh [hSpriteIndexOrTextID], a call IsSpriteInFrontOfPlayer ; check for sprite collisions again? when does the above check fail to detect a sprite collision? + jr nc, .asm_0a5c + res 7, [hl] ldh a, [hSpriteIndexOrTextID] and a ; was there a sprite collision? - jr nz, .collision + jr z, .asm_0a5c ; if no sprite collision + cp $f + jr nz, .collision + call CheckPikachuFollowingPlayer + jr nz, .collision + ldh 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 @@ -1262,19 +1275,7 @@ 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 $ff - jr z, .tileNotPassable - cp c - ret z - jr .loop -.tileNotPassable - scf + call IsTilePassable ret ; check if the player is going to jump down a small ledge @@ -1352,8 +1353,7 @@ LoadCurrentMapView:: ldh a, [hLoadedROMBank] push af ld a, [wTilesetBank] ; tile data ROM bank - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a ; switch to ROM bank that contains tile data + call BankswitchCommon ; switch to ROM bank that contains tile data ld a, [wCurrentTileBlockMapViewPointer] ; address of upper left corner of current map view ld e, a ld a, [wCurrentTileBlockMapViewPointer + 1] @@ -1434,254 +1434,17 @@ LoadCurrentMapView:: dec b jr nz, .rowLoop2 pop af - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a ; restore previous ROM bank + call BankswitchCommon ; restore previous ROM bank ret AdvancePlayerSprite:: - ld a, [wSpritePlayerStateData1YStepVector] - ld b, a - ld a, [wSpritePlayerStateData1XStepVector] - 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 $07 - jp nz, .scrollBackgroundAndSprites -; if this is the first iteration of the animation - ld a, c - cp $01 - jr nz, .checkIfMovingWest -; moving east - ld a, [wMapViewVRAMPointer] - ld e, a - and $e0 - ld d, a - ld a, e - add $02 - and $1f - or d - ld [wMapViewVRAMPointer], a - jr .adjustXCoordWithinBlock -.checkIfMovingWest - cp $ff - jr nz, .checkIfMovingSouth -; moving west - ld a, [wMapViewVRAMPointer] - ld e, a - and $e0 - ld d, a - ld a, e - sub $02 - and $1f - or d - ld [wMapViewVRAMPointer], a - jr .adjustXCoordWithinBlock -.checkIfMovingSouth - ld a, b - cp $01 - jr nz, .checkIfMovingNorth -; moving south - ld a, [wMapViewVRAMPointer] - add $40 - ld [wMapViewVRAMPointer], a - jr nc, .adjustXCoordWithinBlock - ld a, [wMapViewVRAMPointer + 1] - inc a - and $03 - or $98 - ld [wMapViewVRAMPointer + 1], a - jr .adjustXCoordWithinBlock -.checkIfMovingNorth - cp $ff - jr nz, .adjustXCoordWithinBlock -; moving north - ld a, [wMapViewVRAMPointer] - sub $40 - ld [wMapViewVRAMPointer], a - jr nc, .adjustXCoordWithinBlock - ld a, [wMapViewVRAMPointer + 1] - dec a - and $03 - or $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 $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 $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 $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 $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, [wSpritePlayerStateData1YStepVector] - cp $01 - jr nz, .checkIfMovingNorth2 -; if moving south - call ScheduleSouthRowRedraw - jr .scrollBackgroundAndSprites -.checkIfMovingNorth2 - cp $ff - jr nz, .checkIfMovingEast2 -; if moving north - call ScheduleNorthRowRedraw - jr .scrollBackgroundAndSprites -.checkIfMovingEast2 - ld a, [wSpritePlayerStateData1XStepVector] - cp $01 - jr nz, .checkIfMovingWest2 -; if moving east - call ScheduleEastColumnRedraw - jr .scrollBackgroundAndSprites -.checkIfMovingWest2 - cp $ff - jr nz, .scrollBackgroundAndSprites -; if moving west - call ScheduleWestColumnRedraw -.scrollBackgroundAndSprites - ld a, [wSpritePlayerStateData1YStepVector] - ld b, a - ld a, [wSpritePlayerStateData1XStepVector] - ld c, a - sla b - sla c - ldh a, [hSCY] - add b - ldh [hSCY], a ; update background scroll Y - ldh a, [hSCX] - add c - ldh [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, wSprite01StateData1YPixels - 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 $01 - ld [de], a - ret nc - inc de - ld a, [de] - inc a - ld [de], a - ret - -MoveTileBlockMapPointerWest:: - ld a, [de] - sub $01 - ld [de], a - ret nc - inc de - ld a, [de] - dec a - ld [de], a - ret - -MoveTileBlockMapPointerSouth:: - add 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 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 + callfar _AdvancePlayerSprite + pop af + ld [wUpdateSpritesEnabled], a ret ; the following 6 functions are used to tell the V-blank handler to redraw @@ -1826,18 +1589,25 @@ JoypadOverworld:: ld [wSpritePlayerStateData1XStepVector], a call RunMapScript call Joypad + call ForceBikeDown + call AreInputsSimulated + ret + +ForceBikeDown:: ld a, [wFlags_D733] bit 3, a ; check if a trainer wants a challenge - jr nz, .notForcedDownwards + ret nz ld a, [wCurMap] cp ROUTE_17 ; Cycling Road - jr nz, .notForcedDownwards + ret nz ldh a, [hJoyHeld] and D_DOWN | D_UP | D_LEFT | D_RIGHT | B_BUTTON | A_BUTTON - jr nz, .notForcedDownwards + ret nz ld a, D_DOWN ldh [hJoyHeld], a ; on the cycling road, if there isn't a trainer and the player isn't pressing buttons, simulate a down press -.notForcedDownwards + ret + +AreInputsSimulated:: ld a, [wd730] bit 7, a ret z @@ -1847,18 +1617,8 @@ JoypadOverworld:: 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 $ff - jr z, .doneSimulating ; if the end of the simulated button presses has been reached - ld hl, wSimulatedJoypadStatesEnd - add l - ld l, a - jr nc, .noCarry - inc h -.noCarry - ld a, [hl] + call GetSimulatedInput + jr nc, .doneSimulating ldh [hJoyHeld], a ; store simulated button press in joypad state and a ret nz @@ -1882,15 +1642,30 @@ JoypadOverworld:: 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 -; show up. After detecting a sprite collision, it jumps to the code that -; checks if the next tile is passable instead of just directly jumping to the -; "collision detected" code. However, it doesn't store the next tile in c, -; so the old value of c is used. 2429 is always called before this function, -; and 2429 always sets c to 0xF0. There is no 0xF0 background tile, so it -; is considered impassable and it is detected as a collision. +; This function had a bug in Red/Blue, but it was fixed in Yellow. CollisionCheckOnWater:: ld a, [wd730] bit 7, a @@ -1899,31 +1674,17 @@ CollisionCheckOnWater:: ld d, a ld a, [wSpritePlayerStateData1CollisionData] and d ; check if a sprite is in the direction the player is trying to go - jr nz, .checkIfNextTileIsPassable ; bug? + jr nz, .collision ld hl, TilePairCollisionsWater call CheckForJumpingAndTilePairCollisions jr c, .collision predef GetTileAndCoordsInFrontOfPlayer ; get tile in front of player (puts it in c and [wTileInFrontOfPlayer]) + callfar IsNextTileShoreOrWater + jr c, .noCollision ld a, [wTileInFrontOfPlayer] ; tile in front of player - cp $14 ; water tile - jr z, .noCollision ; keep surfing if it's a water tile - cp $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 $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 $ff - jr z, .collision - cp c - jr z, .stopSurfing ; stop surfing if the tile is passable - jr .loop + ld c, a + call IsTilePassable + jr nc, .stopSurfing .collision ld a, [wChannelSoundIDs + Ch5] cp SFX_COLLISION ; check if collision sound is already playing @@ -1933,21 +1694,26 @@ CollisionCheckOnWater:: .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:: @@ -1977,24 +1743,47 @@ RunMapScript:: ret LoadWalkingPlayerSpriteGraphics:: +; new sprite copy stuff + xor a + ld [wd473], a + ld b, BANK(RedSprite) ld de, RedSprite - ld hl, vNPCSprites + 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 jr LoadPlayerSpriteGraphicsCommon LoadSurfingPlayerSpriteGraphics:: + ld b, BANK(SeelSprite) ld de, SeelSprite - ld hl, vNPCSprites jr LoadPlayerSpriteGraphicsCommon LoadBikePlayerSpriteGraphics:: + ld b, BANK(RedBikeSprite) ld de, RedBikeSprite - ld hl, vNPCSprites 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 @@ -2004,12 +1793,17 @@ LoadPlayerSpriteGraphicsCommon:: inc d .noCarry set 3, h - lb bc, BANK(RedSprite), $0c + ld c, $c jp CopyVideoData ; function to load data from the map header LoadMapHeader:: farcall MarkTownVisitedAndLoadMissableObjects + jr asm_0dbd + +Func_0db5:: ; XXX + farcall LoadMissableObjectData +asm_0dbd: ld a, [wCurMapTileset] ld [wUnusedD119], a ld a, [wCurMap] @@ -2021,20 +1815,7 @@ LoadMapHeader:: ldh [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 @@ -2108,155 +1889,19 @@ LoadMapHeader:: 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 - ldh [hSignCoordPointer], a - ld a, e - ldh [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 - ldh a, [hSignCoordPointer] - ld d, a - ldh a, [hSignCoordPointer + 1] - ld e, a - ld a, [hli] - ld [de], a - inc de - ld a, d - ldh [hSignCoordPointer], a - ld a, e - ldh [hSignCoordPointer + 1], a - pop de - dec c - jr nz, .signLoop + call CopySignData .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 out sprite state data for sprites 01-15 - ld hl, wSprite01StateData1 - ld de, wSprite01StateData2 - xor a - ld b, $f0 -.zeroSpriteDataLoop - ld [hli], a - ld [de], a - inc e - dec b - jr nz, .zeroSpriteDataLoop -; disable SPRITESTATEDATA1_IMAGEINDEX (set to $ff) for sprites 01-15 - ld hl, wSprite01StateData1ImageIndex - ld de, $10 - ld c, $0f -.disableSpriteEntriesLoop - ld [hl], $ff - add hl, de - dec c - jr nz, .disableSpriteEntriesLoop - pop hl - ld de, wSprite01StateData1 - 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 ; x#SPRITESTATEDATA1_PICTUREID - inc d - ld a, $04 - add e - ld e, a - ld a, [hli] - ld [de], a ; x#SPRITESTATEDATA2_MAPY - inc e - ld a, [hli] - ld [de], a ; x#SPRITESTATEDATA2_MAPX - inc e - ld a, [hli] - ld [de], a ; x#SPRITESTATEDATA2_MOVEMENTBYTE1 - ld a, [hli] - ldh [hLoadSpriteTemp1], a ; save movement byte 2 - ld a, [hli] - ldh [hLoadSpriteTemp2], a ; save text ID and flags byte - push bc - push hl - ld b, $00 - ld hl, wMapSpriteData - add hl, bc - ldh a, [hLoadSpriteTemp1] - ld [hli], a ; store movement byte 2 in byte 0 of sprite entry - ldh a, [hLoadSpriteTemp2] - ld [hl], a ; this appears pointless, since the value is overwritten immediately after - ldh a, [hLoadSpriteTemp2] - ldh [hLoadSpriteTemp1], a - and $3f - ld [hl], a ; store text ID in byte 1 of sprite entry - pop hl - ldh a, [hLoadSpriteTemp1] - bit 6, a - jr nz, .trainerSprite - bit 7, a - jr nz, .itemBallSprite - jr .regularSprite -.trainerSprite - ld a, [hli] - ldh [hLoadSpriteTemp1], a ; save trainer class - ld a, [hli] - ldh [hLoadSpriteTemp2], a ; save trainer number (within class) - push hl - ld hl, wMapSpriteExtraData - add hl, bc - ldh a, [hLoadSpriteTemp1] - ld [hli], a ; store trainer class in byte 0 of the entry - ldh a, [hLoadSpriteTemp2] - ld [hl], a ; store trainer number in byte 1 of the entry - pop hl - jr .nextSprite -.itemBallSprite - ld a, [hli] - ldh [hLoadSpriteTemp1], a ; save item number - push hl - ld hl, wMapSpriteExtraData - add hl, bc - ldh 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 + jr nz, .finishUp ; if so, skip this because battles don't destroy this data + call InitSprites .finishUp predef LoadTilesetHeader + ld a, [wd72e] + bit 5, a ; did a battle happen immediately before this? + jr nz, .skip_pika_spawn + callfar SchedulePikachuSpawnForAfterText +.skip_pika_spawn callfar LoadWildData 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 @@ -2271,8 +1916,7 @@ LoadMapHeader:: ldh a, [hLoadedROMBank] push af ld a, BANK(MapSongBanks) - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a + call BankswitchCommon ld hl, MapSongBanks add hl, bc add hl, bc @@ -2281,8 +1925,7 @@ LoadMapHeader:: ld a, [hl] ld [wMapMusicROMBank], a ; music 2 pop af - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a + call BankswitchCommon ret ; function to copy map connection data from ROM to WRAM @@ -2297,11 +1940,92 @@ CopyMapConnectionHeader:: 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:: ldh a, [hLoadedROMBank] push af call DisableLCD + call ResetMapVariables + call LoadTextBoxTilePatterns + call LoadMapHeader + call InitMapSprites ; load tile pattern data for sprites + call LoadScreenRelatedData + call CopyMapViewToVRAM + ld a, $01 + ld [wUpdateSpritesEnabled], a + call EnableLCD + ld b, $09 + call 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:: + ldh a, [hLoadedROMBank] + 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 FinishReloadingMap + +ReloadMapAfterPrinter:: + ldh a, [hLoadedROMBank] + push af + ld a, [wCurMap] + call SwitchToMapRomBank + call LoadTileBlockMap + pop af + call BankswitchCommon +FinishReloadingMap: + jpfar SetMapSpecificScriptFlagsOnMapReload + ret ; useless + +ResetMapVariables:: ld a, $98 ld [wMapViewVRAMPointer + 1], a xor a @@ -2310,17 +2034,15 @@ LoadMapData:: ldh [hSCX], a ld [wWalkCounter], a ld [wUnusedD119], a - ld [wWalkBikeSurfStateCopy], a ld [wSpriteSetID], a - call LoadTextBoxTilePatterns - call LoadMapHeader - farcall InitMapSprites ; load tile pattern data for sprites - call LoadTileBlockMap - call LoadTilesetTilePatternData - call LoadCurrentMapView + ld [wWalkBikeSurfStateCopy], a + ret + +CopyMapViewToVRAM:: ; copy current map view to VRAM - hlcoord 0, 0 ld de, vBGMap0 +CopyMapViewToVRAM2: + ld hl, wTileMap ld b, SCREEN_HEIGHT .vramCopyLoop ld c, SCREEN_WIDTH @@ -2338,24 +2060,6 @@ LoadMapData:: .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 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 - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a ret ; function to switch to the ROM bank that a map is stored in @@ -2373,12 +2077,30 @@ SwitchToMapRomBank:: ldh [hMapROMBank], a call BankswitchBack ldh a, [hMapROMBank] - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a + call BankswitchCommon pop bc pop hl ret +GetMapHeaderPointer:: + ldh a, [hLoadedROMBank] + push af + ld a, BANK(MapHeaderPointers) + call BankswitchCommon + 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 @@ -2399,6 +2121,163 @@ ForceBikeOrSurf:: 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 + farcall _HandleMidJump + ret + +IsSpinning:: + ld a, [wd736] + bit 7, a + ret z ; no spinning + farjp LoadSpinnerArrowTiles ; spin while moving + +Func_0ffe:: + jpfar 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, wSprite01StateData1 +; copy sprite stuff? +.loadSpriteLoop + ld a, [hli] + ld [de], a ; x#SPRITESTATEDATA1_PICTUREID + inc d + ld a, e + add $4 + ld e, a + ld a, [hli] + ld [de], a ; x#SPRITESTATEDATA2_MAPY + inc e + ld a, [hli] + ld [de], a ; x#SPRITESTATEDATA2_MAPX + inc e + ld a, [hli] + ld [de], a ; x#SPRITESTATEDATA2_MOVEMENTBYTE1 + ld a, [hli] + ldh [hLoadSpriteTemp1], a ; save movement byte 2 + ld a, [hli] + ldh [hLoadSpriteTemp2], 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 out sprite state data for sprites 01-14 +; sprite 15 is used for Pikachu + ld hl, wSprite01StateData1 + ld de, wSprite01StateData2 + xor a + ld b, 14 * $10 +.loop + ld [hli], a + ld [de], a + inc e + dec b + jr nz, .loop + ret + +DisableRegularSprites:: +; disable SPRITESTATEDATA1_IMAGEINDEX (set to $ff) for sprites 01-14 + ld hl, wSprite01StateData1ImageIndex + 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 + ldh a, [hLoadSpriteTemp1] + ld [hli], a ; store movement byte 2 in byte 0 of sprite entry + ldh a, [hLoadSpriteTemp2] + ld [hl], a ; this appears pointless, since the value is overwritten immediately after + ldh a, [hLoadSpriteTemp2] + ldh [hLoadSpriteTemp1], a + and $3f + ld [hl], a ; store text ID in byte 1 of sprite entry + pop hl + ldh a, [hLoadSpriteTemp1] + 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] + ldh [hLoadSpriteTemp1], a ; save trainer class + ld a, [hli] + ldh [hLoadSpriteTemp2], a ; save trainer number (within class) + push hl + ld hl, wMapSpriteExtraData + add hl, bc + ldh a, [hLoadSpriteTemp1] + ld [hli], a ; store trainer class in byte 0 of the entry + ldh a, [hLoadSpriteTemp2] + ld [hl], a ; store trainer number in byte 1 of the entry + pop hl + ret + +.itemBallSprite + ld a, [hli] + ldh [hLoadSpriteTemp1], a ; save item number + push hl + ld hl, wMapSpriteExtraData + add hl, bc + ldh 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 + ret + CheckForUserInterruption:: ; Return carry if Up+Select+B, Start or A are pressed in c frames. ; Used only in the intro and title screen. diff --git a/home/palettes.asm b/home/palettes.asm index 08dcdc85..af66e74b 100644 --- a/home/palettes.asm +++ b/home/palettes.asm @@ -1,3 +1,6 @@ +InitMapSprites:: + jpfar _InitMapSprites + RestoreScreenTilesAndReloadTilePatterns:: call ClearSprites ld a, $1 @@ -23,6 +26,9 @@ GBPalNormal:: ldh [rBGP], a ld a, %11010000 ; 3100 ldh [rOBP0], a + call UpdateGBCPal_BGP + call UpdateGBCPal_OBP0 + call UpdateGBCPal_OBP1 ret GBPalWhiteOut:: @@ -31,6 +37,9 @@ GBPalWhiteOut:: ldh [rBGP], a ldh [rOBP0], a ldh [rOBP1], a + call UpdateGBCPal_BGP + call UpdateGBCPal_OBP0 + call UpdateGBCPal_OBP1 ret RunDefaultPaletteCommand:: diff --git a/home/pics.asm b/home/pics.asm index 3bce1532..c0559908 100644 --- a/home/pics.asm +++ b/home/pics.asm @@ -18,10 +18,6 @@ UncompressMonSprite:: ; $99 ≤ index: bank $D ("Pics 5") ld a, [wcf91] ld b, a - cp MEW - ld a, BANK(MewPicFront) - jr z, .GotBank - ld a, b cp FOSSIL_KABUTOPS ld a, BANK(FossilKabutopsPic) jr z, .GotBank @@ -92,8 +88,8 @@ LoadUncompressedSpriteData:: add a add a ; 8*(7*((8-w)/2) + 7-h) ; combined overall offset (in bytes) ldh [hSpriteOffset], a - xor a - ld [MBC1SRamBank], a + ld a, $0 + call SwitchSRAMBankAndLatchClockData ld hl, sSpriteBuffer0 call ZeroSpriteBuffer ; zero buffer 0 ld de, sSpriteBuffer1 @@ -104,6 +100,7 @@ LoadUncompressedSpriteData:: ld de, sSpriteBuffer2 ld hl, sSpriteBuffer1 call AlignSpriteDataCentered ; copy and align buffer 2 to 1 (containing the LSB of the 2bpp sprite) + call PrepareRTCDataAndDisableSRAM pop de jp InterlaceMergeSpriteBuffers @@ -150,8 +147,8 @@ ZeroSpriteBuffer:: ; in the resulting sprite, the rows of the two source sprites are interlaced ; de: output address InterlaceMergeSpriteBuffers:: - xor a - ld [MBC1SRamBank], a + ld a, $0 + call SwitchSRAMBankAndLatchClockData push de ld hl, sSpriteBuffer2 + (SPRITEBUFFERSIZE - 1) ; destination: end of buffer 2 ld de, sSpriteBuffer1 + (SPRITEBUFFERSIZE - 1) ; source 2: end of buffer 1 @@ -193,4 +190,5 @@ InterlaceMergeSpriteBuffers:: ld c, (2*SPRITEBUFFERSIZE)/16 ; $31, number of 16 byte chunks to be copied ldh a, [hLoadedROMBank] ld b, a - jp CopyVideoData + call CopyVideoData + jp PrepareRTCDataAndDisableSRAM diff --git a/home/pikachu.asm b/home/pikachu.asm new file mode 100644 index 00000000..ae6acfe3 --- /dev/null +++ b/home/pikachu.asm @@ -0,0 +1,116 @@ +Func_1510:: + push hl + ld hl, wPikachuOverworldStateFlags + set 7, [hl] + ld hl, wSpritePikachuStateData1ImageIndex ; 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, wSpritePikachuStateData1ImageIndex ; 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 + ldh [hTilePlayerStandingOn], a + homecall SpawnPikachu_ + 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 + ldh a, [hLoadedROMBank] + 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:: + ldh a, [hLoadedROMBank] + ld b, a + push af + ld a, BANK(ApplyPikachuMovementData_) + call BankswitchCommon + call ApplyPikachuMovementData_ + pop af + call BankswitchCommon + ret diff --git a/home/pikachu_cries.asm b/home/pikachu_cries.asm new file mode 100644 index 00000000..84889ef9 --- /dev/null +++ b/home/pikachu_cries.asm @@ -0,0 +1,46 @@ +PlayPikachuPCM:: + ldh a, [hLoadedROMBank] + push af + ld a, b + call BankswitchCommon + ld a, [hli] + ld c, a + ld a, [hli] + ld b, a +.loop + ld a, [hli] + ld d, a + ld a, $3 +.playSingleSample + dec a + jr nz, .playSingleSample + +REPT 7 + call LoadNextSoundClipSample + call PlaySoundClipSample +ENDR + + call LoadNextSoundClipSample + dec bc + ld a, c + or b + jr nz, .loop + pop af + call BankswitchCommon + ret + +LoadNextSoundClipSample:: + ld a, d + and $80 + srl a + srl a + ldh [rNR32], a + sla d + ret + +PlaySoundClipSample:: + ld a, $3 +.loop + dec a + jr nz, .loop + ret diff --git a/home/play_time.asm b/home/play_time.asm new file mode 100644 index 00000000..d6c95fbd --- /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 + ldh [hJoyPressed], a + ldh [hJoyHeld], a + ret diff --git a/home/pokemon.asm b/home/pokemon.asm index 4e6e080b..93b536ff 100644 --- a/home/pokemon.asm +++ b/home/pokemon.asm @@ -5,7 +5,6 @@ DrawHPBar:: push hl push de - push bc ; Left ld a, $71 ; "HP:" @@ -61,7 +60,6 @@ DrawHPBar:: add e ld [hl], a .done - pop bc pop de pop hl ret @@ -125,24 +123,32 @@ LoadFrontSpriteByMonIndex:: ldh a, [hLoadedROMBank] push af ld a, BANK(CopyUncompressedPicToHL) - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a + call BankswitchCommon xor a ldh [hStartTileID], a call CopyUncompressedPicToHL xor a ld [wSpriteFlipped], a pop af - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a - ret + jp BankswitchCommon PlayCry:: ; Play monster a's cry. + push bc + ld b, a + ld a, [wLowHealthAlarm] + push af + xor a + ld [wLowHealthAlarm], a + ld a, b call GetCryData call PlaySound - jp WaitForSoundToFinish + call WaitForSoundToFinish + pop af + ld [wLowHealthAlarm], a + pop bc + ret GetCryData:: ; Load cry data for monster a. @@ -239,12 +245,23 @@ HandlePartyMenuInput:: ld a, $40 ld [wPartyMenuAnimMonEnabled], a call HandleMenuInput_ - call PlaceUnfilledArrowMenuCursor - ld b, a - xor a + push af ; save hJoy5 OR wMenuWrapping enabled, if no inputs were selected within a certain period of time + bit 1, a ; was B button pressed? + ld a, $0 ld [wPartyMenuAnimMonEnabled], a ld a, [wCurrentMenuItem] ld [wPartyAndBillsPCSavedMenuItem], a + jr nz, .asm_1258 + ld a, [wCurrentMenuItem] + ld [wWhichPokemon], a + callfar IsThisPartymonStarterPikachu_Party + jr nc, .asm_1258 + call CheckPikachuFollowingPlayer + jr nz, .asm_128f +.asm_1258 + pop af + call PlaceUnfilledArrowMenuCursor + ld b, a ld hl, wd730 res 6, [hl] ; turn on letter printing delay ld a, [wMenuItemToSwap] @@ -269,6 +286,14 @@ HandlePartyMenuInput:: call BankswitchBack and a ret +.asm_128f + pop af + ld hl, PartyMenuText_12cc + call PrintText + xor a + ld [wMenuItemToSwap], a + pop af + ldh [hTileAnimations], a .noPokemonChosen call BankswitchBack scf @@ -282,12 +307,16 @@ HandlePartyMenuInput:: ld [wMenuItemToSwap], a ld [wPartyMenuTypeOrMessageID], a call RedrawPartyMenu - jr HandlePartyMenuInput + jp HandlePartyMenuInput .handleSwap ld a, [wCurrentMenuItem] ld [wWhichPokemon], a farcall SwitchPartyMon - jr HandlePartyMenuInput + jp HandlePartyMenuInput + +PartyMenuText_12cc:: + text_far _SleepingPikachuText1 + text_end DrawPartyMenu:: ld hl, DrawPartyMenu_ @@ -325,8 +354,7 @@ PrintStatusCondition:: ret PrintStatusConditionNotFainted:: - homecall_sf PrintStatusAilment - ret + homejp_sf PrintStatusAilment ; function to print pokemon level, leaving off the ":L" if the level is at least 100 ; INPUT: @@ -376,8 +404,7 @@ GetMonHeader:: ldh a, [hLoadedROMBank] push af ld a, BANK(BaseStats) - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a + call BankswitchCommon push bc push de push hl @@ -396,8 +423,6 @@ GetMonHeader:: ld b, $77 ; size of Aerodactyl fossil sprite cp FOSSIL_AERODACTYL ; Aerodactyl fossil jr z, .specialID - cp MEW - jr z, .mew predef IndexToPokedex ; convert pokemon ID in [wd11e] to pokedex number ld a, [wd11e] dec a @@ -415,13 +440,6 @@ GetMonHeader:: ld [hl], e ; write front sprite pointer inc hl ld [hl], d - jr .done -.mew - ld hl, MewBaseStats - ld de, wMonHeader - ld bc, BASE_DATA_SIZE - ld a, BANK(MewBaseStats) - call FarCopyData .done ld a, [wd0b5] ld [wMonHIndex], a @@ -431,8 +449,7 @@ GetMonHeader:: pop de pop bc pop af - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a + call BankswitchCommon ret ; copy party pokemon's name to wcd6d diff --git a/home/predef.asm b/home/predef.asm index 14ac07b5..4861d5d0 100644 --- a/home/predef.asm +++ b/home/predef.asm @@ -19,8 +19,7 @@ Predef:: call GetPredefPointer ld a, [wPredefBank] - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a + call BankswitchCommon ld de, .done push de @@ -28,8 +27,7 @@ Predef:: .done pop af - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a + call BankswitchCommon ret GetPredefRegisters:: diff --git a/home/print_num.asm b/home/print_num.asm index e2628b1f..d86527a6 100644 --- a/home/print_num.asm +++ b/home/print_num.asm @@ -1,3 +1,14 @@ +FarPrintText:: +; print text b:hl at (1, 14) + ldh a, [hLoadedROMBank] + push af + ld a, b + call BankswitchCommon + call PrintText + pop af + call BankswitchCommon + ret + PrintNumber:: ; Print the c-digit, b-byte value at de. ; Allows 2 to 7 digits. For 1-digit numbers, add diff --git a/home/printer.asm b/home/printer.asm new file mode 100644 index 00000000..6d9f145c --- /dev/null +++ b/home/printer.asm @@ -0,0 +1,34 @@ + +PrinterSerial:: + homecall PrinterSerial_ + ret + +SerialFunction:: + ld a, [wPrinterConnectionOpen] + bit 0, a + ret z + ld a, [wPrinterOpcode] + and a + ret nz + ld hl, wOverworldMap + 650 + inc [hl] + ld a, [hl] + cp $6 + ret c + xor a + ld [hl], a + ld a, $0c + ld [wPrinterOpcode], a + ld a, $88 + ldh [rSB], a + ld a, $1 + ldh [rSC], a + ld a, START_TRANSFER_INTERNAL_CLOCK + ldh [rSC], a + ret + +; causes the text box to close without waiting for a button press after displaying text +DisableWaitingAfterTextDisplay:: + ld a, $01 + ld [wDoNotWaitForButtonPressAfterDisplayingText], a + ret diff --git a/home/reload_sprites.asm b/home/reload_sprites.asm index 8a08d64d..63a71d26 100644 --- a/home/reload_sprites.asm +++ b/home/reload_sprites.asm @@ -9,7 +9,7 @@ ReloadMapSpriteTilePatterns:: xor a ld [wSpriteSetID], a call DisableLCD - farcall InitMapSprites + call InitMapSprites call EnableLCD pop hl pop af diff --git a/home/reload_tiles.asm b/home/reload_tiles.asm index 6228395c..b596263a 100644 --- a/home/reload_tiles.asm +++ b/home/reload_tiles.asm @@ -10,8 +10,7 @@ ReloadMapData:: call LoadTilesetTilePatternData call EnableLCD pop af - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a + call BankswitchCommon ret ; reloads tileset tile patterns @@ -24,8 +23,7 @@ ReloadTilesetTilePatterns:: call LoadTilesetTilePatternData call EnableLCD pop af - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a + call BankswitchCommon ret ; shows the town map and lets the player choose a destination to fly to @@ -33,9 +31,3 @@ ChooseFlyDestination:: ld hl, wd72e res 4, [hl] farjp LoadTownMap_Fly - -; causes the text box to close without waiting for a button press after displaying text -DisableWaitingAfterTextDisplay:: - ld a, $01 - ld [wDoNotWaitForButtonPressAfterDisplayingText], a - ret diff --git a/home/reset_player_sprite.asm b/home/reset_player_sprite.asm index 72df31a1..2765d613 100644 --- a/home/reset_player_sprite.asm +++ b/home/reset_player_sprite.asm @@ -17,4 +17,5 @@ ResetPlayerSpriteData:: ResetPlayerSpriteData_ClearSpriteData:: ld bc, $10 xor a - jp FillMemory + call FillMemory + ret diff --git a/home/serial.asm b/home/serial.asm index bd984d4f..ef914933 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__ ldh a, [hSerialConnectionStatus] inc a jr z, .connectionNotYetEstablished @@ -310,3 +313,11 @@ Serial_TryEstablishingExternallyClockedConnection:: ld a, START_TRANSFER_EXTERNAL_CLOCK ldh [rSC], a ret + +PrinterSerial__:: + call PrinterSerial + pop hl + pop de + pop bc + pop af + reti diff --git a/home/start.asm b/home/start.asm index 764f9468..366806e9 100644 --- a/home/start.asm +++ b/home/start.asm @@ -4,7 +4,7 @@ _Start:: xor a jr .ok .gbc - ld a, FALSE + ld a, TRUE .ok - ld [wGBC], a + ldh [hGBC], a jp Init diff --git a/home/start_menu.asm b/home/start_menu.asm index 5b29f67a..8edccfe2 100644 --- a/home/start_menu.asm +++ b/home/start_menu.asm @@ -1,7 +1,6 @@ DisplayStartMenu:: - ld a, BANK(StartMenu_Pokedex) - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a + ld a, BANK(StartMenu_Pokedex) ; also bank for other functions + call BankswitchCommon ld a, [wWalkBikeSurfState] ; walking/biking/surfing ld [wWalkBikeSurfStateCopy], a ld a, SFX_START_MENU @@ -9,6 +8,7 @@ DisplayStartMenu:: RedisplayStartMenu:: farcall DrawStartMenu +RedisplayStartMenu_DoNotDrawStartMenu:: farcall PrintSafariZoneSteps ; print Safari Zone info, if in Safari Zone call UpdateSprites .loop diff --git a/home/text.asm b/home/text.asm index 244c6fdb..a8571722 100644 --- a/home/text.asm +++ b/home/text.asm @@ -239,6 +239,13 @@ Paragraph:: jp NextChar PageChar:: + ldh a, [hUILayoutFlags] + bit 3, a + jr z, .pageChar + ld a, "<NEXT>" + jp PlaceNextChar.NotTerminator + +.pageChar push de ld a, "▼" ldcoord_a 18, 16 @@ -516,7 +523,7 @@ TextCommand_SOUND:: jr .loop .play - cp TX_SOUND_CRY_NIDORINA + cp TX_SOUND_CRY_PIKACHU jr z, .pokemonCry cp TX_SOUND_CRY_PIDGEOT jr z, .pokemonCry @@ -546,9 +553,9 @@ TextCommandSounds:: db TX_SOUND_GET_ITEM_2, SFX_GET_ITEM_2 db TX_SOUND_GET_KEY_ITEM, SFX_GET_KEY_ITEM db TX_SOUND_DEX_PAGE_ADDED, SFX_DEX_PAGE_ADDED - db TX_SOUND_CRY_NIDORINA, NIDORINA ; used in OakSpeech - db TX_SOUND_CRY_PIDGEOT, PIDGEOT ; used in SaffronCityText12 - db TX_SOUND_CRY_DEWGONG, DEWGONG ; unused + db TX_SOUND_CRY_PIKACHU, STARTER_PIKACHU ; used in OakSpeech + db TX_SOUND_CRY_PIDGEOT, PIDGEOT ; used in SaffronCityText12 + db TX_SOUND_CRY_DEWGONG, DEWGONG ; unused TextCommand_DOTS:: ; wait for button press or 30 frames while printing "…"s diff --git a/home/text_script.asm b/home/text_script.asm index a6881dc5..5ef9f9fa 100644 --- a/home/text_script.asm +++ b/home/text_script.asm @@ -1,3 +1,7 @@ +UnknownText_2812:: ; unreferenced + text_far _PokemonText + text_end + ; this function is used to display sign messages, sprite dialog, etc. ; INPUT: [hSpriteIndexOrTextID] = sprite ID or text ID DisplayTextID:: @@ -22,6 +26,7 @@ DisplayTextID:: ld [wSpriteIndex], a dict TEXT_START_MENU, DisplayStartMenu + dict TEXT_PIKACHU_ANIM, DisplayPikachuEmotion dict TEXT_SAFARI_GAME_OVER, DisplaySafariGameOverText dict TEXT_MON_FAINTED, DisplayPokemonFaintedText dict TEXT_BLACKED_OUT, DisplayPlayerBlackedOutText @@ -36,20 +41,13 @@ DisplayTextID:: .spriteHandling ; get the text ID of the sprite push hl - push de - push bc - farcall UpdateSpriteFacingOffsetAndDelayMovement ; update the graphics of the sprite the player is talking to (to face the right direction) - pop bc - pop de ld hl, wMapSpriteData ; NPC text entries ldh a, [hSpriteIndexOrTextID] dec a add a - add l - ld l, a - jr nc, .noCarry - inc h -.noCarry + ld e, a + ld d, 0 + add hl, de inc hl ld a, [hl] ; a = text ID of the sprite pop hl @@ -57,7 +55,8 @@ DisplayTextID:: ; look up the address of the text in the map's text entries dec a ld e, a - sla e + ld d, 0 + add hl, de add hl, de ld a, [hli] ld h, [hl] @@ -122,9 +121,6 @@ CloseTextDisplay:: add hl, de dec c jr nz, .restoreSpriteFacingDirectionLoop - ld a, BANK(InitMapSprites) - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a call InitMapSprites ; reload sprite tile pattern data (since it was partially overwritten by text tile patterns) ld hl, wFontLoaded res 0, [hl] @@ -133,8 +129,7 @@ CloseTextDisplay:: call z, LoadPlayerSpriteGraphics call LoadCurrentMapView pop af - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a + call BankswitchCommon jp UpdateSprites DisplayPokemartDialogue:: @@ -199,6 +194,16 @@ DisplayPlayerBlackedOutText:: ld a, [wd732] res 5, a ; reset forced to use bike bit ld [wd732], a + CheckEvent EVENT_IN_SAFARI_ZONE + jr z, .didnotblackoutinsafari + xor a + ld [wNumSafariBalls], a + ld [wSafariSteps], a + ld [wSafariSteps + 1], a + EventFlagAddressA EVENT_IN_SAFARI_ZONE + ld [wcf0d], a + ld [wSafariZoneGateCurScript], a +.didnotblackoutinsafari jp HoldTextDisplayOpen PlayerBlackedOutText:: @@ -213,3 +218,7 @@ DisplayRepelWoreOffText:: RepelWoreOffText:: text_far _RepelWoreOffText text_end + +DisplayPikachuEmotion:: + callfar TalkToPikachu + jp CloseTextDisplay diff --git a/home/tilemap.asm b/home/tilemap.asm index afee7097..ea247763 100644 --- a/home/tilemap.asm +++ b/home/tilemap.asm @@ -1,17 +1,3 @@ -FillMemory:: -; Fill bc bytes at hl with a. - push de - ld d, a -.loop - ld a, d - ld [hli], a - dec bc - ld a, b - or c - jr nz, .loop - pop de - ret - UncompressSpriteFromDE:: ; Decompress pic at a:de. ld hl, wSpriteInputPtr @@ -24,8 +10,7 @@ SaveScreenTilesToBuffer2:: hlcoord 0, 0 ld de, wTileMapBackup2 ld bc, SCREEN_WIDTH * SCREEN_HEIGHT - call CopyData - ret + jp CopyData LoadScreenTilesFromBuffer2:: call LoadScreenTilesFromBuffer2DisableBGTransfer @@ -40,8 +25,7 @@ LoadScreenTilesFromBuffer2DisableBGTransfer:: ld hl, wTileMapBackup2 decoord 0, 0 ld bc, SCREEN_WIDTH * SCREEN_HEIGHT - call CopyData - ret + jp CopyData SaveScreenTilesToBuffer1:: hlcoord 0, 0 diff --git a/home/trainers.asm b/home/trainers.asm index 4dc63fef..468b63f8 100644 --- a/home/trainers.asm +++ b/home/trainers.asm @@ -383,17 +383,6 @@ TrainerEndBattleText:: call TextCommandProcessor jp TextScriptEnd -; only engage with the trainer if the player is not already -; engaged with another trainer -; XXX unused? -CheckIfAlreadyEngaged:: - ld a, [wFlags_0xcd60] - bit 0, a - ret nz - call EngageMapTrainer - xor a - ret - PlayTrainerMusic:: ld a, [wEngagedTrainerClass] cp OPP_RIVAL1 @@ -407,8 +396,7 @@ PlayTrainerMusic:: ret nz xor a ld [wAudioFadeOutControl], a - ld a, SFX_STOP_ALL_MUSIC - call PlaySound + call StopAllMusic ld a, BANK(Music_MeetEvilTrainer) ld [wAudioROMBank], a ld [wAudioSavedROMBank], a diff --git a/home/trainers2.asm b/home/trainers2.asm index 950eabb2..78fb6463 100644 --- a/home/trainers2.asm +++ b/home/trainers2.asm @@ -22,6 +22,7 @@ GetTrainerInformation:: inc de ld a, [hli] ld [de], a + call IsFightingJessieJames jp BankswitchBack .linkBattle ld hl, wTrainerPicPointer @@ -31,5 +32,23 @@ GetTrainerInformation:: ld [hl], d ret +IsFightingJessieJames:: + ld a, [wTrainerClass] + cp ROCKET + ret nz + ld a, [wTrainerNo] + cp $2a + ret c + ld de, JessieJamesPic + cp $2e + jr c, .dummy + ld de, JessieJamesPic ; possibly meant to add another pic +.dummy + ld hl, wTrainerPicPointer + ld a, e + ld [hli], a + ld [hl], d + ret + GetTrainerName:: farjp GetTrainerName_ diff --git a/home/uncompress.asm b/home/uncompress.asm index d3d84b26..27474f2d 100644 --- a/home/uncompress.asm +++ b/home/uncompress.asm @@ -5,16 +5,13 @@ UncompressSpriteData:: ldh a, [hLoadedROMBank] push af ld a, b - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a - ld a, SRAM_ENABLE - ld [MBC1SRamEnable], a - xor a - ld [MBC1SRamBank], a + call BankswitchCommon + ld a, $0 + call SwitchSRAMBankAndLatchClockData call _UncompressSpriteData + call PrepareRTCDataAndDisableSRAM pop af - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a + call BankswitchCommon ret ; initializes necessary data to load a sprite and runs UncompressSpriteDataLoop diff --git a/home/update_sprites.asm b/home/update_sprites.asm index 5530c2a4..5bb9ee12 100644 --- a/home/update_sprites.asm +++ b/home/update_sprites.asm @@ -2,5 +2,15 @@ UpdateSprites:: ld a, [wUpdateSpritesEnabled] dec a ret nz - homecall _UpdateSprites + ldh a, [hLoadedROMBank] + push af + ld a, BANK(_UpdateSprites) + call BankswitchCommon + ld a, $ff + ld [wUpdateSpritesEnabled], a + call _UpdateSprites + ld a, $1 + ld [wUpdateSpritesEnabled], a + pop af + call BankswitchCommon ret diff --git a/home/vblank.asm b/home/vblank.asm index 4c7abc20..3957639a 100644 --- a/home/vblank.asm +++ b/home/vblank.asm @@ -5,6 +5,11 @@ VBlank:: push de push hl + ldh a, [rVBK] ; vram bank + push af + xor a + ldh [rVBK], a ; reset vram bank to 0 + ldh a, [hLoadedROMBank] ld [wVBlankSavedROMBank], a @@ -33,8 +38,10 @@ VBlank:: call PrepareOAMData ; VBlank-sensitive operations end. + call TrackPlayTime ; keep track of time played call Random + call ReadJoypad ldh a, [hVBlankOccurred] and a @@ -52,36 +59,22 @@ VBlank:: .skipDec call FadeOutAudio - ld a, [wAudioROMBank] ; music ROM bank - ldh [hLoadedROMBank], a - ld [MBC1RomBank], a - - cp BANK(Audio1_UpdateMusic) - jr nz, .checkForAudio2 -.audio1 - call Audio1_UpdateMusic - jr .afterMusic -.checkForAudio2 - cp BANK(Audio2_UpdateMusic) - jr nz, .audio3 -.audio2 + ld a, BANK(Music_DoLowHealthAlarm) + call BankswitchCommon call Music_DoLowHealthAlarm - call Audio2_UpdateMusic - jr .afterMusic -.audio3 - call Audio3_UpdateMusic -.afterMusic - - farcall TrackPlayTime ; keep track of time played + ld a, BANK(Audio1_UpdateMusic) + call BankswitchCommon + call Audio1_UpdateMusic - ldh a, [hDisableJoypadPolling] - and a - call z, ReadJoypad + call SerialFunction ld a, [wVBlankSavedROMBank] ldh [hLoadedROMBank], a ld [MBC1RomBank], a + pop af + ldh [rVBK], a + pop hl pop de pop bc diff --git a/home/vcopy.asm b/home/vcopy.asm index 0b0e0144..4a80d261 100644 --- a/home/vcopy.asm +++ b/home/vcopy.asm @@ -123,11 +123,7 @@ AutoBgMapTransfer:: ldh a, [hAutoBGTransferEnabled] and a ret z - ld hl, sp + 0 - ld a, h - ldh [hSPTemp], a - ld a, l - ldh [hSPTemp + 1], a ; save stack pinter + ld [hSPTemp], sp ; save stack pointer ldh a, [hAutoBGTransferPortion] and a jr z, .transferTopThird @@ -191,9 +187,9 @@ ENDR jr nz, TransferBgRows ldh a, [hSPTemp] - ld h, a - ldh a, [hSPTemp + 1] ld l, a + ldh a, [hSPTemp + 1] + ld h, a ld sp, hl ret @@ -203,11 +199,7 @@ VBlankCopyBgMap:: ldh a, [hVBlankCopyBGSource] ; doubles as enabling byte and a ret z - ld hl, sp + 0 - ld a, h - ldh [hSPTemp], a - ld a, l - ldh [hSPTemp + 1], a ; save stack pointer + ld [hSPTemp], sp ; save stack pointer ldh a, [hVBlankCopyBGSource] ld l, a ldh a, [hVBlankCopyBGSource + 1] @@ -236,11 +228,7 @@ VBlankCopyDouble:: and a ret z - ld hl, sp + 0 - ld a, h - ldh [hSPTemp], a - ld a, l - ldh [hSPTemp + 1], a + ld [hSPTemp], sp ; save stack pointer ldh a, [hVBlankCopyDoubleSource] ld l, a @@ -282,21 +270,14 @@ ENDR dec b jr nz, .loop - ld a, l - ldh [hVBlankCopyDoubleDest], a - ld a, h - ldh [hVBlankCopyDoubleDest + 1], a - - ld hl, sp + 0 - ld a, l - ldh [hVBlankCopyDoubleSource], a - ld a, h - ldh [hVBlankCopyDoubleSource + 1], a + ld [hVBlankCopyDoubleSource], sp + ld sp, hl ; load destination into sp to save time with ld [$xxxx], sp + ld [hVBlankCopyDoubleDest], sp ldh a, [hSPTemp] - ld h, a - ldh a, [hSPTemp + 1] ld l, a + ldh a, [hSPTemp + 1] + ld h, a ld sp, hl ret @@ -313,11 +294,7 @@ VBlankCopy:: and a ret z - ld hl, sp + 0 - ld a, h - ldh [hSPTemp], a - ld a, l - ldh [hSPTemp + 1], a + ld [hSPTemp], sp ldh a, [hVBlankCopySource] ld l, a @@ -351,21 +328,14 @@ ENDR dec b jr nz, .loop - ld a, l - ldh [hVBlankCopyDest], a - ld a, h - ldh [hVBlankCopyDest + 1], a - - ld hl, sp + 0 - ld a, l - ldh [hVBlankCopySource], a - ld a, h - ldh [hVBlankCopySource + 1], a + ld [hVBlankCopySource], sp + ld sp, hl + ld [hVBlankCopyDest], sp ldh a, [hSPTemp] - ld h, a - ldh a, [hSPTemp + 1] ld l, a + ldh a, [hSPTemp + 1] + ld h, a ld sp, hl ret @@ -379,6 +349,10 @@ UpdateMovingBgTiles:: and a ret z ; no animations if indoors (or if a menu set this to 0) + ldh a, [rLY] + cp $90 ; check if not in vblank period??? (maybe if vblank is too long) + ret c + ldh a, [hMovingBGTilesCounter1] inc a ldh [hMovingBGTilesCounter1], a diff --git a/home/window.asm b/home/window.asm index 0182bdd3..1be272f9 100644 --- a/home/window.asm +++ b/home/window.asm @@ -50,6 +50,8 @@ HandleMenuInput_:: ld [wCheckFor180DegreeTurn], a ldh a, [hJoy5] ld b, a + bit 0, a ; pressed A key? + jr nz, .checkOtherKeys bit 6, a ; pressed Up key? jr z, .checkIfDownPressed .upPressed @@ -135,15 +137,13 @@ PlaceMenuCursor:: ld a, [wLastMenuItem] and a ; was the previous menu id 0? jr z, .checkForArrow1 + ld bc, 40 push af ldh a, [hUILayoutFlags] bit 1, a ; is the menu double spaced? jr z, .doubleSpaced1 ld bc, 20 - jr .getOldMenuItemScreenPosition .doubleSpaced1 - ld bc, 40 -.getOldMenuItemScreenPosition pop af .oldMenuItemLoop add hl, bc @@ -161,15 +161,13 @@ PlaceMenuCursor:: ld a, [wCurrentMenuItem] and a jr z, .checkForArrow2 + ld bc, 40 push af ldh a, [hUILayoutFlags] bit 1, a ; is the menu double spaced? jr z, .doubleSpaced2 ld bc, 20 - jr .getCurrentMenuItemScreenPosition .doubleSpaced2 - ld bc, 40 -.getCurrentMenuItemScreenPosition pop af .currentMenuItemLoop add hl, bc diff --git a/home/yes_no.asm b/home/yes_no.asm index 5b0e09ed..28d6c7aa 100644 --- a/home/yes_no.asm +++ b/home/yes_no.asm @@ -5,7 +5,7 @@ YesNoChoice:: call InitYesNoTextBoxParameters jr DisplayYesNoChoice -Func_35f4:: +Func_35f7:: ld a, TWO_OPTION_MENU ld [wTextBoxID], a call InitYesNoTextBoxParameters |