diff options
author | dannye <33dannye@gmail.com> | 2020-11-04 00:06:44 -0600 |
---|---|---|
committer | dannye <33dannye@gmail.com> | 2020-11-04 00:06:44 -0600 |
commit | 5647ca687b92954dcf37a6ea6bfbc9a341c32de4 (patch) | |
tree | dde1937a1bfdb3a835f4155e1c2eb8f1aaf86f63 /home.asm | |
parent | 53fcd05aa24693093d8af1dc8ec4fedd3957decc (diff) |
Sync with pokered
Diffstat (limited to 'home.asm')
-rw-r--r-- | home.asm | 4801 |
1 files changed, 77 insertions, 4724 deletions
@@ -1,105 +1,23 @@ -; The rst vectors are unused. -SECTION "rst 00", ROM0 - rst $38 -SECTION "rst 08", ROM0 - rst $38 -SECTION "rst 10", ROM0 - rst $38 -SECTION "rst 18", ROM0 - rst $38 -SECTION "rst 20", ROM0 - rst $38 -SECTION "rst 28", ROM0 - rst $38 -SECTION "rst 30", ROM0 - rst $38 -SECTION "rst 38", ROM0 - rst $38 +INCLUDE "constants.asm" -; Hardware interrupts -SECTION "vblank", ROM0 - jp VBlank -SECTION "hblank", ROM0 - jp LCDC -SECTION "timer", ROM0 - jp Timer -SECTION "serial", ROM0 - jp Serial -SECTION "joypad", ROM0 - reti +SECTION "NULL", ROM0 +NULL:: -SECTION "Home", ROM0 - -DisableLCD:: - xor a - ld [rIF], a - ld a, [rIE] - ld b, a - res 0, a - ld [rIE], a +INCLUDE "home/header.asm" -.wait - ld a, [rLY] - cp LY_VBLANK - jr nz, .wait - ld a, [rLCDC] - and $ff ^ rLCDC_ENABLE_MASK - ld [rLCDC], a - ld a, b - ld [rIE], a - ret - -EnableLCD:: - ld a, [rLCDC] - set rLCDC_ENABLE, a - ld [rLCDC], a - ret - -ClearSprites:: - xor a - ld hl, wOAMBuffer - ld b, 40 * 4 -.loop - ld [hli], a - dec b - jr nz, .loop - ret - -HideSprites:: - ld a, 160 - ld hl, wOAMBuffer - ld de, 4 - ld b, 40 -.loop - ld [hl], a - add hl, de - dec b - jr nz, .loop - ret +SECTION "High Home", ROM0 +INCLUDE "home/lcd.asm" +INCLUDE "home/clear_sprites.asm" INCLUDE "home/copy.asm" -SECTION "Entry", ROM0 - - nop - jp Start - - -SECTION "Header", ROM0 - - ; The header is generated by rgbfix. - ; The space here is allocated to prevent code from being overwritten. - - ds $150 - $104 - - -SECTION "Main", ROM0 +SECTION "Home", ROM0 PlayPikachuPCM:: - ld a, [H_LOADEDROMBANK] + ldh a, [hLoadedROMBank] push af ld a, b call BankswitchCommon @@ -134,7 +52,7 @@ LoadNextSoundClipSample:: and $80 srl a srl a - ld [rNR32], a + ldh [rNR32], a sla d ret @@ -145,830 +63,15 @@ PlaySoundClipSample:: jr nz, .loop ret -Start:: - cp GBC - jr z, .gbc - xor a - jr .ok -.gbc - ld a, 1 -.ok - ld [hGBC], a - jp Init - -Joypad:: - homecall_jump _Joypad - -ReadJoypad:: - homecall_jump ReadJoypad_ +INCLUDE "home/start.asm" +INCLUDE "home/joypad.asm" INCLUDE "home/overworld.asm" - -CheckForUserInterruption:: -; Return carry if Up + Select + B, Start or A are pressed in c frames. -; Used only in the intro and title screen. - call DelayFrame - - push bc - call JoypadLowSensitivity - pop bc - - ld a, [hJoyHeld] - cp D_UP + SELECT + B_BUTTON - jr z, .input - - ld a, [hJoy5] - and START | A_BUTTON - jr nz, .input - - dec c - jr nz, CheckForUserInterruption - - and a - ret - -.input - scf - ret - -; function to load position data for destination warp when switching maps -; INPUT: -; a = ID of destination warp within destination map -LoadDestinationWarpPosition:: - ld b, a - ld a, [H_LOADEDROMBANK] - push af - ld a, [wPredefParentBank] - ld [H_LOADEDROMBANK], a - ld [MBC1RomBank], a - ld a, b - add a - add a - ld c, a - ld b, 0 - add hl, bc - ld bc, 4 - ld de, wCurrentTileBlockMapViewPointer - call CopyData - pop af - ld [H_LOADEDROMBANK], a - ld [MBC1RomBank], a - ret - - -DrawHPBar:: -; Draw an HP bar d tiles long, and fill it to e pixels. -; If c is nonzero, show at least a sliver regardless. -; The right end of the bar changes with [wHPBarType]. - - push hl - push de - ;push bc - - ; Left - ld a, $71 ; "HP:" - ld [hli], a - ld a, $62 - ld [hli], a - - push hl - - ; Middle - ld a, $63 ; empty -.draw - ld [hli], a - dec d - jr nz, .draw - - ; Right - ld a, [wHPBarType] - dec a - ld a, $6d ; status screen and battle - jr z, .ok - dec a ; pokemon menu -.ok - ld [hl], a - - pop hl - - ld a, e - and a - jr nz, .fill - - ; If c is nonzero, draw a pixel anyway. - ld a, c - and a - jr z, .done - ld e, 1 - -.fill - ld a, e - sub 8 - jr c, .partial - ld e, a - ld a, $6b ; full - ld [hli], a - ld a, e - and a - jr z, .done - jr .fill - -.partial - ; Fill remaining pixels at the end if necessary. - ld a, $63 ; empty - add e - ld [hl], a -.done - ;pop bc - pop de - pop hl - ret - - -; loads pokemon data from one of multiple sources to wLoadedMon -; loads base stats to wMonHeader -; INPUT: -; [wWhichPokemon] = index of pokemon within party/box -; [wMonDataLocation] = source -; 00: player's party -; 01: enemy's party -; 02: current box -; 03: daycare -; OUTPUT: -; [wcf91] = pokemon ID -; wLoadedMon = base address of pokemon data -; wMonHeader = base address of base stats -LoadMonData:: - jpab LoadMonData_ - -OverwritewMoves:: -; Write c to [wMoves + b]. Unused. - ld hl, wMoves - ld e, b - ld d, 0 - add hl, de - ld a, c - ld [hl], a - ret - -LoadFlippedFrontSpriteByMonIndex:: - ld a, 1 - ld [wSpriteFlipped], a - -LoadFrontSpriteByMonIndex:: - push hl - ld a, [wd11e] - push af - ld a, [wcf91] - ld [wd11e], a - predef IndexToPokedex - ld hl, wd11e - ld a, [hl] - pop bc - ld [hl], b - and a - pop hl - jr z, .invalidDexNumber ; dex #0 invalid - cp NUM_POKEMON + 1 - jr c, .validDexNumber ; dex >#151 invalid -.invalidDexNumber - ld a, RHYDON ; $1 - ld [wcf91], a - ret -.validDexNumber - push hl - ld de, vFrontPic - call LoadMonFrontSprite - pop hl - ld a, [H_LOADEDROMBANK] - push af - switchbank CopyUncompressedPicToHL - xor a - ld [hStartTileID], a - call CopyUncompressedPicToHL - xor a - ld [wSpriteFlipped], a - pop af - 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 - call WaitForSoundToFinish - pop af - ld [wLowHealthAlarm], a - pop bc - ret - -GetCryData:: -; Load cry data for monster a. - dec a - ld c, a - ld b, 0 - ld hl, CryData - add hl, bc - add hl, bc - add hl, bc - - ld a, BANK(CryData) - call BankswitchHome - ld a, [hli] - ld b, a ; cry id - ld a, [hli] - ld [wFrequencyModifier], a - ld a, [hl] - ld [wTempoModifier], a - call BankswitchBack - - ; Cry headers have 3 channels, - ; and start from index $14, - ; so add 3 times the cry id. - ld a, b - ld c, $14 - rlca ; * 2 - add b - add c - ret - -DisplayPartyMenu:: - ld a, [hTilesetType] - push af - xor a - ld [hTilesetType], a - call GBPalWhiteOutWithDelay3 - call ClearSprites - call PartyMenuInit - call DrawPartyMenu - jp HandlePartyMenuInput - -GoBackToPartyMenu:: - ld a, [hTilesetType] - push af - xor a - ld [hTilesetType], a - call PartyMenuInit - call RedrawPartyMenu - jp HandlePartyMenuInput - -PartyMenuInit:: - ld a, 1 ; hardcoded bank - call BankswitchHome - call LoadHpBarAndStatusTilePatterns - ld hl, wd730 - set 6, [hl] ; turn off letter printing delay - xor a ; PLAYER_PARTY_DATA - ld [wMonDataLocation], a - ld [wMenuWatchMovingOutOfBounds], a - ld hl, wTopMenuItemY - inc a - ld [hli], a ; top menu item Y - xor a - ld [hli], a ; top menu item X - ld a, [wPartyAndBillsPCSavedMenuItem] - push af - ld [hli], a ; current menu item ID - inc hl - ld a, [wPartyCount] - and a ; are there more than 0 pokemon in the party? - jr z, .storeMaxMenuItemID - dec a -; if party is not empty, the max menu item ID is ([wPartyCount] - 1) -; otherwise, it is 0 -.storeMaxMenuItemID - ld [hli], a ; max menu item ID - ld a, [wForcePlayerToChooseMon] - and a - ld a, A_BUTTON | B_BUTTON - jr z, .next - xor a - ld [wForcePlayerToChooseMon], a - inc a ; a = A_BUTTON -.next - ld [hli], a ; menu watched keys - pop af - ld [hl], a ; old menu item ID - ret - -HandlePartyMenuInput:: - ld a, 1 - ld [wMenuWrappingEnabled], a - ld a, $40 - ld [wPartyMenuAnimMonEnabled], a - call HandleMenuInputPokemonSelection - 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 - callab 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] - and a - jp nz, .swappingPokemon - pop af - ld [hTilesetType], a - bit 1, b - jr nz, .noPokemonChosen - ld a, [wPartyCount] - and a - jr z, .noPokemonChosen - ld a, [wCurrentMenuItem] - ld [wWhichPokemon], a - ld hl, wPartySpecies - ld b, 0 - ld c, a - add hl, bc - ld a, [hl] - ld [wcf91], a - ld [wBattleMonSpecies2], a - call BankswitchBack - and a - ret -.asm_128f - pop af - ld hl, PartyMenuText_12cc - call PrintText - xor a - ld [wMenuItemToSwap], a - pop af - ld [hTilesetType], a -.noPokemonChosen - call BankswitchBack - scf - ret -.swappingPokemon - bit 1, b ; was the B button pressed? - jr z, .handleSwap ; if not, handle swapping the pokemon -.cancelSwap ; if the B button was pressed - callba ErasePartyMenuCursors - xor a - ld [wMenuItemToSwap], a - ld [wPartyMenuTypeOrMessageID], a - call RedrawPartyMenu - jp HandlePartyMenuInput -.handleSwap - ld a, [wCurrentMenuItem] - ld [wWhichPokemon], a - callba SwitchPartyMon - jp HandlePartyMenuInput - -PartyMenuText_12cc:: - TX_FAR _SleepingPikachuText1 - db "@" - -DrawPartyMenu:: - ld hl, DrawPartyMenu_ - jr DrawPartyMenuCommon - -RedrawPartyMenu:: - ld hl, RedrawPartyMenu_ - -DrawPartyMenuCommon:: - ld b, BANK(RedrawPartyMenu_) - jp Bankswitch - -; prints a pokemon's status condition -; INPUT: -; de = address of status condition -; hl = destination address -PrintStatusCondition:: - push de - dec de - dec de ; de = address of current HP - ld a, [de] - ld b, a - dec de - ld a, [de] - or b ; is the pokemon's HP zero? - pop de - jr nz, PrintStatusConditionNotFainted -; if the pokemon's HP is 0, print "FNT" - ld a, "F" - ld [hli], a - ld a, "N" - ld [hli], a - ld [hl], "T" - and a - ret - -PrintStatusConditionNotFainted: - homecall_jump_sf PrintStatusAilment - -; function to print pokemon level, leaving off the ":L" if the level is at least 100 -; INPUT: -; hl = destination address -; [wLoadedMonLevel] = level -PrintLevel:: - ld a, $6e ; ":L" tile ID - ld [hli], a - ld c, 2 ; number of digits - ld a, [wLoadedMonLevel] ; level - cp 100 - jr c, PrintLevelCommon -; if level at least 100, write over the ":L" tile - dec hl - inc c ; increment number of digits to 3 - jr PrintLevelCommon - -; prints the level without leaving off ":L" regardless of level -; INPUT: -; hl = destination address -; [wLoadedMonLevel] = level -PrintLevelFull:: - ld a, $6e ; ":L" tile ID - ld [hli], a - ld c, 3 ; number of digits - ld a, [wLoadedMonLevel] ; level - -PrintLevelCommon:: - ld [wd11e], a - ld de, wd11e - ld b, LEFT_ALIGN | 1 ; 1 byte - jp PrintNumber - -GetwMoves:: -; Unused. Returns the move at index a from wMoves in a - ld hl, wMoves - ld c, a - ld b, 0 - add hl, bc - ld a, [hl] - ret - -; copies the base stat data of a pokemon to wMonHeader -; INPUT: -; [wd0b5] = pokemon ID -GetMonHeader:: - ld a, [H_LOADEDROMBANK] - push af - switchbank BaseStats - push bc - push de - push hl - ld a, [wd11e] - push af - ld a, [wd0b5] - ld [wd11e], a - ld de, FossilKabutopsPic - ld b, $66 ; size of Kabutops fossil and Ghost sprites - cp FOSSIL_KABUTOPS ; Kabutops fossil - jr z, .specialID - ld de, GhostPic - cp MON_GHOST ; Ghost - jr z, .specialID - ld de, FossilAerodactylPic - 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 - ld bc, MonBaseStatsEnd - MonBaseStats - ld hl, BaseStats - call AddNTimes - ld de, wMonHeader - ld bc, MonBaseStatsEnd - MonBaseStats - call CopyData - jr .done -.specialID - ld hl, wMonHSpriteDim - ld [hl], b ; write sprite dimensions - inc hl - ld [hl], e ; write front sprite pointer - inc hl - ld [hl], d -.done - ld a, [wd0b5] - ld [wMonHIndex], a - pop af - ld [wd11e], a - pop hl - pop de - pop bc - pop af - call BankswitchCommon - ret - -; copy party pokemon's name to wcd6d -GetPartyMonName2:: - ld a, [wWhichPokemon] ; index within party - ld hl, wPartyMonNicks - -; this is called more often -GetPartyMonName:: - push hl - push bc - call SkipFixedLengthTextEntries ; add NAME_LENGTH to hl, a times - ld de, wcd6d - push de - ld bc, NAME_LENGTH - call CopyData - pop de - pop bc - pop hl - ret - -; function to print a BCD (Binary-coded decimal) number -; de = address of BCD number -; hl = destination address -; c = flags and length -; bit 7: if set, do not print leading zeroes -; if unset, print leading zeroes -; bit 6: if set, left-align the string (do not pad empty digits with spaces) -; if unset, right-align the string -; bit 5: if set, print currency symbol at the beginning of the string -; if unset, do not print the currency symbol -; bits 0-4: length of BCD number in bytes -; Note that bits 5 and 7 are modified during execution. The above reflects -; their meaning at the beginning of the functions's execution. -PrintBCDNumber:: - ld b, c ; save flags in b - res 7, c - res 6, c - res 5, c ; c now holds the length - bit 5, b - jr z, .loop - bit 7, b - jr nz, .loop - ld [hl], "¥" - inc hl -.loop - ld a, [de] - swap a - call PrintBCDDigit ; print upper digit - ld a, [de] - call PrintBCDDigit ; print lower digit - inc de - dec c - jr nz, .loop - bit 7, b ; were any non-zero digits printed? - jr z, .done ; if so, we are done -.numberEqualsZero ; if every digit of the BCD number is zero - bit 6, b ; left or right alignment? - jr nz, .skipRightAlignmentAdjustment - dec hl ; if the string is right-aligned, it needs to be moved back one space -.skipRightAlignmentAdjustment - bit 5, b - jr z, .skipCurrencySymbol - ld [hl], "¥" - inc hl -.skipCurrencySymbol - ld [hl], "0" - call PrintLetterDelay - inc hl -.done - ret - -PrintBCDDigit:: - and $f - and a - jr z, .zeroDigit -.nonzeroDigit - bit 7, b ; have any non-space characters been printed? - jr z, .outputDigit -; if bit 7 is set, then no numbers have been printed yet - bit 5, b ; print the currency symbol? - jr z, .skipCurrencySymbol - ld [hl], "¥" - inc hl - res 5, b -.skipCurrencySymbol - res 7, b ; unset 7 to indicate that a nonzero digit has been reached -.outputDigit - add "0" - ld [hli], a - jp PrintLetterDelay -.zeroDigit - bit 7, b ; either printing leading zeroes or already reached a nonzero digit? - jr z, .outputDigit ; if so, print a zero digit - bit 6, b ; left or right alignment? - ret nz - inc hl ; if right-aligned, "print" a space by advancing the pointer - ret - -; uncompresses the front or back sprite of the specified mon -; assumes the corresponding mon header is already loaded -; hl contains offset to sprite pointer ($b for front or $d for back) -UncompressMonSprite:: - ld bc, wMonHeader - add hl, bc - ld a, [hli] - ld [wSpriteInputPtr], a ; fetch sprite input pointer - ld a, [hl] - ld [wSpriteInputPtr + 1], a -; define (by index number) the bank that a pokemon's image is in -; index = Mew, bank 1 -; index = Kabutops fossil, bank $B -; index < $1F, bank 9 -; $1F ≤ index < $4A, bank $A -; $4A ≤ index < $74, bank $B -; $74 ≤ index < $99, bank $C -; $99 ≤ index, bank $D - ld a, [wcf91] ; XXX name for this ram location - 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 - ld a, b - cp TANGELA + 1 - ld a, BANK(TangelaPicFront) - jr c, .GotBank - ld a, b - cp MOLTRES + 1 - ld a, BANK(MoltresPicFront) - jr c, .GotBank - ld a, b - cp BEEDRILL + 2 - ld a, BANK(BeedrillPicFront) - jr c, .GotBank - ld a, b - cp STARMIE + 1 - ld a, BANK(StarmiePicFront) - jr c, .GotBank - ld a, BANK(VictreebelPicFront) -.GotBank - jp UncompressSpriteData - -; de: destination location -LoadMonFrontSprite:: - push de - ld hl, wMonHFrontSprite - wMonHeader - call UncompressMonSprite - ld hl, wMonHSpriteDim - ld a, [hli] - ld c, a - pop de - ; fall through - -; postprocesses uncompressed sprite chunks to a 2bpp sprite and loads it into video ram -; calculates alignment parameters to place both sprite chunks in the center of the 7*7 tile sprite buffers -; de: destination location -; a, c: sprite dimensions (in tiles of 8x8 each) -LoadUncompressedSpriteData:: - push de - and $f - ld [H_SPRITEWIDTH], a ; each byte contains 8 pixels (in 1bpp), so tiles=bytes for width - ld b, a - ld a, $7 - sub b ; 7-w - inc a ; 8-w - srl a ; (8-w)/2 ; horizontal center (in tiles, rounded up) - ld b, a - add a - add a - add a - sub b ; 7*((8-w)/2) ; skip for horizontal center (in tiles) - ld [H_SPRITEOFFSET], a - ld a, c - swap a - and $f - ld b, a - add a - add a - add a ; 8*tiles is height in bytes - ld [H_SPRITEHEIGHT], a - ld a, $7 - sub b ; 7-h ; skip for vertical center (in tiles, relative to current column) - ld b, a - ld a, [H_SPRITEOFFSET] - add b ; 7*((8-w)/2) + 7-h ; combined overall offset (in tiles) - add a - add a - add a ; 8*(7*((8-w)/2) + 7-h) ; combined overall offset (in bytes) - ld [H_SPRITEOFFSET], a - ld a, $0 - call SwitchSRAMBankAndLatchClockData - ld hl, sSpriteBuffer0 - call ZeroSpriteBuffer ; zero buffer 0 - ld de, sSpriteBuffer1 - ld hl, sSpriteBuffer0 - call AlignSpriteDataCentered ; copy and align buffer 1 to 0 (containing the MSB of the 2bpp sprite) - ld hl, sSpriteBuffer1 - call ZeroSpriteBuffer ; zero buffer 1 - 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 - -; copies and aligns the sprite data properly inside the sprite buffer -; sprite buffers are 7*7 tiles in size, the loaded sprite is centered within this area -AlignSpriteDataCentered:: - ld a, [H_SPRITEOFFSET] - ld b, $0 - ld c, a - add hl, bc - ld a, [H_SPRITEWIDTH] -.columnLoop - push af - push hl - ld a, [H_SPRITEHEIGHT] - ld c, a -.columnInnerLoop - ld a, [de] - inc de - ld [hli], a - dec c - jr nz, .columnInnerLoop - pop hl - ld bc, 7*8 ; 7 tiles - add hl, bc ; advance one full column - pop af - dec a - jr nz, .columnLoop - ret - -; fills the sprite buffer (pointed to in hl) with zeros -ZeroSpriteBuffer:: - ld bc, SPRITEBUFFERSIZE -.nextByteLoop - xor a - ld [hli], a - dec bc - ld a, b - or c - jr nz, .nextByteLoop - ret - -; combines the (7*7 tiles, 1bpp) sprite chunks in buffer 0 and 1 into a 2bpp sprite located in buffer 1 through 2 -; in the resulting sprite, the rows of the two source sprites are interlaced -; de: output address -InterlaceMergeSpriteBuffers:: - 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 - ld bc, sSpriteBuffer0 + (SPRITEBUFFERSIZE - 1) ; source 1: end of buffer 0 - ld a, SPRITEBUFFERSIZE/2 ; $c4 - ld [H_SPRITEINTERLACECOUNTER], a -.interlaceLoop - ld a, [de] - dec de - ld [hld], a ; write byte of source 2 - ld a, [bc] - dec bc - ld [hld], a ; write byte of source 1 - ld a, [de] - dec de - ld [hld], a ; write byte of source 2 - ld a, [bc] - dec bc - ld [hld], a ; write byte of source 1 - ld a, [H_SPRITEINTERLACECOUNTER] - dec a - ld [H_SPRITEINTERLACECOUNTER], a - jr nz, .interlaceLoop - ld a, [wSpriteFlipped] - and a - jr z, .notFlipped - ld bc, 2*SPRITEBUFFERSIZE - ld hl, sSpriteBuffer1 -.swapLoop - swap [hl] ; if flipped swap nybbles in all bytes - inc hl - dec bc - ld a, b - or c - jr nz, .swapLoop -.notFlipped - pop hl - ld de, sSpriteBuffer1 - ld c, (2*SPRITEBUFFERSIZE)/16 ; $31, number of 16 byte chunks to be copied - ld a, [H_LOADEDROMBANK] - ld b, a - call CopyVideoData - jp PrepareRTCDataAndDisableSRAM +INCLUDE "home/pokemon.asm" +INCLUDE "home/print_bcd.asm" +INCLUDE "home/pics.asm" INCLUDE "home/pikachu.asm" -;INCLUDE "data/collision.asm" INCLUDE "home/lcdc.asm" @@ -987,1240 +90,43 @@ INCLUDE "home/play_time.asm" INCLUDE "home/serial.asm" INCLUDE "home/timer.asm" INCLUDE "home/audio.asm" +INCLUDE "home/update_sprites.asm" +INCLUDE "data/items/marts.asm" -UpdateSprites:: - ld a, [wUpdateSpritesEnabled] - dec a - ret nz - ld a, [H_LOADEDROMBANK] - push af - switchbank _UpdateSprites - ld a, $ff - ld [wUpdateSpritesEnabled], a - call _UpdateSprites - ld a, $1 - ld [wUpdateSpritesEnabled], a - pop af - call BankswitchCommon - ret - -INCLUDE "data/mart_inventories.asm" - -TextScriptEndingChar:: - db "@" -TextScriptEnd:: - ld hl, TextScriptEndingChar - ret - -ExclamationText:: - TX_FAR _ExclamationText - db "@" - -GroundRoseText:: - TX_FAR _GroundRoseText - db "@" - -BoulderText:: - TX_FAR _BoulderText - db "@" - -MartSignText:: - TX_FAR _MartSignText - db "@" - -PokeCenterSignText:: - TX_FAR _PokeCenterSignText - db "@" - -PickUpItemText:: - TX_ASM - predef PickUpItem - jp TextScriptEnd - - -INCLUDE "home/pic.asm" - - -ResetPlayerSpriteData:: - ld hl, wSpriteStateData1 - call ResetPlayerSpriteData_ClearSpriteData - ld hl, wSpriteStateData2 - call ResetPlayerSpriteData_ClearSpriteData - ld a, $1 - ld [wSpriteStateData1], a - ld [wSpriteStateData2 + $0e], a - ld hl, wSpriteStateData1 + 4 - ld [hl], $3c ; set Y screen pos - inc hl - inc hl - ld [hl], $40 ; set X screen pos - ret - -; overwrites sprite data with zeroes -ResetPlayerSpriteData_ClearSpriteData:: - ld bc, $10 - xor a - call FillMemory - ret - -FadeOutAudio:: - ld a, [wAudioFadeOutControl] - and a ; currently fading out audio? - jr nz, .fadingOut - ld a, [wd72c] - bit 1, a - ret nz - ld a, $77 - ld [rNR50], a - ret -.fadingOut - ld a, [wAudioFadeOutCounter] - and a - jr z, .counterReachedZero - dec a - ld [wAudioFadeOutCounter], a - ret -.counterReachedZero - ld a, [wAudioFadeOutCounterReloadValue] - ld [wAudioFadeOutCounter], a - ld a, [rNR50] - and a ; has the volume reached 0? - jr z, .fadeOutComplete - ld b, a - and $f - dec a - ld c, a - ld a, b - and $f0 - swap a - dec a - swap a - or c - ld [rNR50], a - ret -.fadeOutComplete - ld a, [wAudioFadeOutControl] - ld b, a - xor a - ld [wAudioFadeOutControl], a - call StopAllMusic - ld a, [wAudioSavedROMBank] - ld [wAudioROMBank], a - ld a, b - ld [wNewSoundID], a - jp PlaySound +INCLUDE "home/overworld_text.asm" +INCLUDE "home/uncompress.asm" +INCLUDE "home/reset_player_sprite.asm" +INCLUDE "home/fade_audio.asm" UnknownText_2812:: - TX_FAR _PokemonText - db "@" - -; this function is used to display sign messages, sprite dialog, etc. -; INPUT: [hSpriteIndexOrTextID] = sprite ID or text ID -DisplayTextID:: - ld a, [H_LOADEDROMBANK] - push af - callba DisplayTextIDInit ; initialization - ld hl, wTextPredefFlag - bit 0, [hl] - res 0, [hl] - jr nz, .skipSwitchToMapBank - ld a, [wCurMap] - call SwitchToMapRomBank -.skipSwitchToMapBank - ld a, 30 ; half a second - ld [H_FRAMECOUNTER], a ; used as joypad poll timer - ld hl, wMapTextPtr - ld a, [hli] - ld h, [hl] - ld l, a ; hl = map text pointer - ld d, $00 - ld a, [hSpriteIndexOrTextID] ; text ID - ld [wSpriteIndex], a - and a - jp z, DisplayStartMenu - cp TEXT_PIKACHU_ANIM - jp z, DisplayPikachuEmotion - cp TEXT_SAFARI_GAME_OVER - jp z, DisplaySafariGameOverText - cp TEXT_MON_FAINTED - jp z, DisplayPokemonFaintedText - cp TEXT_BLACKED_OUT - jp z, DisplayPlayerBlackedOutText - cp TEXT_REPEL_WORE_OFF - jp z, DisplayRepelWoreOffText - ld a, [wNumSprites] - ld e, a - ld a, [hSpriteIndexOrTextID] ; sprite ID - cp e - jr z, .spriteHandling - jr nc, .skipSpriteHandling -.spriteHandling -; get the text ID of the sprite - push hl - ;push de - ;push bc - ;callba 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 - ld a, [hSpriteIndexOrTextID] - dec a - add a - ld e, a - ld d, $0 - add hl, de - inc hl - ld a, [hl] ; a = text ID of the sprite - pop hl -.skipSpriteHandling -; look up the address of the text in the map's text entries - dec a - ld e, a - ld d, $0 - add hl, de - add hl, de - ld a, [hli] - ld h, [hl] - ld l, a ; hl = address of the text - ld a, [hl] ; a = first byte of text -; check first byte of text for special cases - cp $fe ; Pokemart NPC - jp z, DisplayPokemartDialogue - cp $ff ; Pokemon Center NPC - jp z, DisplayPokemonCenterDialogue - cp $fc ; Item Storage PC - jp z, FuncTX_ItemStoragePC - cp $fd ; Bill's PC - jp z, FuncTX_BillsPC - cp $f9 ; Pokemon Center PC - jp z, FuncTX_PokemonCenterPC - cp $f5 ; Vending Machine - jr nz, .notVendingMachine - callba VendingMachineMenu ; jump banks to vending machine routine - jr AfterDisplayingTextID -.notVendingMachine - cp $f7 ; prize menu - jp z, FuncTX_GameCornerPrizeMenu - cp $f6 ; cable connection NPC in Pokemon Center - jr nz, .notSpecialCase - callab CableClubNPC - jr AfterDisplayingTextID -.notSpecialCase - call PrintText_NoCreatingTextBox ; display the text - ld a, [wDoNotWaitForButtonPressAfterDisplayingText] - and a - jr nz, HoldTextDisplayOpen - -AfterDisplayingTextID:: - ld a, [wEnteringCableClub] - and a - jr nz, HoldTextDisplayOpen - call WaitForTextScrollButtonPress ; wait for a button press after displaying all the text - -; loop to hold the dialogue box open as long as the player keeps holding down the A button -HoldTextDisplayOpen:: - call Joypad - ld a, [hJoyHeld] - bit 0, a ; is the A button being pressed? - jr nz, HoldTextDisplayOpen - -CloseTextDisplay:: - ld a, [wCurMap] - call SwitchToMapRomBank - ld a, $90 - ld [hWY], a ; move the window off the screen - call DelayFrame - call LoadGBPal - xor a - ld [H_AUTOBGTRANSFERENABLED], a ; disable continuous WRAM to VRAM transfer each V-blank -; loop to make sprites face the directions they originally faced before the dialogue - ld hl, wSpriteStateData2 + $19 - ld c, $0f - ld de, $0010 -.restoreSpriteFacingDirectionLoop - ld a, [hl] - dec h - ld [hl], a - inc h - add hl, de - dec c - jr nz, .restoreSpriteFacingDirectionLoop - call InitMapSprites ; reload sprite tile pattern data (since it was partially overwritten by text tile patterns) - ld hl, wFontLoaded - res 0, [hl] - ld a, [wd732] - bit 3, a ; used fly warp - call z, LoadPlayerSpriteGraphics - call LoadCurrentMapView - pop af - call BankswitchCommon - jp UpdateSprites - -DisplayPokemartDialogue:: - push hl - ld hl, PokemartGreetingText - call PrintText - pop hl - inc hl - call LoadItemList - ld a, PRICEDITEMLISTMENU - ld [wListMenuID], a - homecall DisplayPokemartDialogue_ - jp AfterDisplayingTextID - -PokemartGreetingText:: - TX_FAR _PokemartGreetingText - db "@" - -LoadItemList:: - ld a, 1 - ld [wUpdateSpritesEnabled], a - ld a, h - ld [wItemListPointer], a - ld a, l - ld [wItemListPointer + 1], a - ld de, wItemList -.loop - ld a, [hli] - ld [de], a - inc de - cp $ff - jr nz, .loop - ret - -DisplayPokemonCenterDialogue:: -; zeroing these doesn't appear to serve any purpose - xor a - ld [$ff8b], a - ld [$ff8c], a - ld [$ff8d], a - - inc hl - homecall DisplayPokemonCenterDialogue_ - jp AfterDisplayingTextID - -DisplaySafariGameOverText:: - callab PrintSafariGameOverText - jp AfterDisplayingTextID - -DisplayPokemonFaintedText:: - ld hl, PokemonFaintedText - call PrintText - jp AfterDisplayingTextID - -PokemonFaintedText:: - TX_FAR _PokemonFaintedText - db "@" - -DisplayPlayerBlackedOutText:: - ld hl, PlayerBlackedOutText - call PrintText - 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:: - TX_FAR _PlayerBlackedOutText - db "@" - -DisplayRepelWoreOffText:: - ld hl, RepelWoreOffText - call PrintText - jp AfterDisplayingTextID - -RepelWoreOffText:: - TX_FAR _RepelWoreOffText - db "@" - -DisplayPikachuEmotion:: - callab TalkToPikachu - jp CloseTextDisplay - -INCLUDE "engine/menu/start_menu.asm" - -; function to count how many bits are set in a string of bytes -; INPUT: -; hl = address of string of bytes -; b = length of string of bytes -; OUTPUT: -; [wNumSetBits] = number of set bits -CountSetBits:: - ld c, 0 -.loop - ld a, [hli] - ld e, a - ld d, 8 -.innerLoop ; count how many bits are set in the current byte - srl e - ld a, 0 - adc c - ld c, a - dec d - jr nz, .innerLoop - dec b - jr nz, .loop - ld a, c - ld [wNumSetBits], a - ret - -; subtracts the amount the player paid from their money -; sets carry flag if there is enough money and unsets carry flag if not -SubtractAmountPaidFromMoney:: - jpba SubtractAmountPaidFromMoney_ - -; adds the amount the player sold to their money -AddAmountSoldToMoney:: - ld de, wPlayerMoney + 2 - ld hl, hMoney + 2 ; total price of items - ld c, 3 ; length of money in bytes - predef AddBCDPredef ; add total price to money - ld a, MONEY_BOX - ld [wTextBoxID], a - call DisplayTextBoxID ; redraw money text box - ld a, SFX_PURCHASE - call PlaySoundWaitForCurrent - jp WaitForSoundToFinish - -; function to remove an item (in varying quantities) from the player's bag or PC box -; INPUT: -; HL = address of inventory (either wNumBagItems or wNumBoxItems) -; [wWhichPokemon] = index (within the inventory) of the item to remove -; [wItemQuantity] = quantity to remove -RemoveItemFromInventory:: - homecall RemoveItemFromInventory_ - ret - -; function to add an item (in varying quantities) to the player's bag or PC box -; INPUT: -; HL = address of inventory (either wNumBagItems or wNumBoxItems) -; [wcf91] = item ID -; [wItemQuantity] = item quantity -; sets carry flag if successful, unsets carry flag if unsuccessful -AddItemToInventory:: - push bc - homecall_sf AddItemToInventory_ - pop bc - ret - -; INPUT: -; [wListMenuID] = list menu ID -; [wListPointer] = address of the list (2 bytes) -DisplayListMenuID:: - xor a - ld [H_AUTOBGTRANSFERENABLED], a ; disable auto-transfer - ld a, 1 - ld [hJoy7], a ; joypad state update flag - ld a, [wBattleType] - and a ; is it the Old Man battle? - jr nz, .specialBattleType - ld a, $01 ; hardcoded bank - jr .bankswitch -.specialBattleType ; Old Man battle - ld a, BANK(DisplayBattleMenu) -.bankswitch - call BankswitchHome - ld hl, wd730 - set 6, [hl] ; turn off letter printing delay - xor a - ld [wMenuItemToSwap], a ; 0 means no item is currently being swapped - ld [wListCount], a - ld a, [wListPointer] - ld l, a - ld a, [wListPointer + 1] - ld h, a ; hl = address of the list - ld a, [hl] ; the first byte is the number of entries in the list - ld [wListCount], a - ld a, LIST_MENU_BOX - ld [wTextBoxID], a - call DisplayTextBoxID ; draw the menu text box - call UpdateSprites ; disable sprites behind the text box -; the code up to .skipMovingSprites appears to be useless - coord hl, 4, 2 ; coordinates of upper left corner of menu text box - lb de, 9, 14 ; height and width of menu text box - ld a, [wListMenuID] - and a ; is it a PC pokemon list? - jr nz, .skipMovingSprites - call UpdateSprites -.skipMovingSprites - ld a, 1 ; max menu item ID is 1 if the list has less than 2 entries - ld [wMenuWatchMovingOutOfBounds], a - ld a, [wListCount] - cp 2 ; does the list have less than 2 entries? - jr c, .setMenuVariables - ld a, 2 ; max menu item ID is 2 if the list has at least 2 entries -.setMenuVariables - ld [wMaxMenuItem], a - ld a, 4 - ld [wTopMenuItemY], a - ld a, 5 - ld [wTopMenuItemX], a - ld a, A_BUTTON | B_BUTTON | SELECT - ld [wMenuWatchedKeys], a - ld c, 10 - call DelayFrames - -DisplayListMenuIDLoop:: - xor a - ld [H_AUTOBGTRANSFERENABLED], a ; disable transfer - call PrintListMenuEntries - ld a, 1 - ld [H_AUTOBGTRANSFERENABLED], a ; enable transfer - call Delay3 - ld a, [wBattleType] - and a ; is it the Old Man battle? - jr z, .notOldManBattle -.oldManBattle - ld a, "▶" - Coorda 5, 4 ; place menu cursor in front of first menu entry - ld c, 20 - call DelayFrames - xor a - ld [wCurrentMenuItem], a - coord hl, 5, 4 - ld a, l - ld [wMenuCursorLocation], a - ld a, h - ld [wMenuCursorLocation + 1], a - jr .buttonAPressed -.notOldManBattle - call LoadGBPal - call HandleMenuInput - push af - call PlaceMenuCursor - pop af - bit 0, a ; was the A button pressed? - jp z, .checkOtherKeys -.buttonAPressed - ld a, [wCurrentMenuItem] - call PlaceUnfilledArrowMenuCursor - -; pointless because both values are overwritten before they are read - ld a, $01 - ld [wMenuExitMethod], a - ld [wChosenMenuItem], a - - xor a - ld [wMenuWatchMovingOutOfBounds], a - ld a, [wCurrentMenuItem] - ld c, a - ld a, [wListScrollOffset] - add c - ld c, a - ld a, [wListCount] - and a ; is the list empty? - jp z, ExitListMenu ; if so, exit the menu - dec a - cp c ; did the player select Cancel? - jp c, ExitListMenu ; if so, exit the menu - ld a, c - ld [wWhichPokemon], a - ld a, [wListMenuID] - cp ITEMLISTMENU - jr nz, .skipMultiplying -; if it's an item menu - sla c ; item entries are 2 bytes long, so multiply by 2 -.skipMultiplying - ld a, [wListPointer] - ld l, a - ld a, [wListPointer + 1] - ld h, a - inc hl ; hl = beginning of list entries - ld b, 0 - add hl, bc - ld a, [hl] - ld [wcf91], a - ld a, [wListMenuID] - and a ; is it a PC pokemon list? - jr z, .pokemonList - push hl - call GetItemPrice - pop hl - ld a, [wListMenuID] - cp ITEMLISTMENU - jr nz, .skipGettingQuantity -; if it's an item menu - inc hl - ld a, [hl] ; a = item quantity - ld [wMaxItemQuantity], a -.skipGettingQuantity - ld a, [wcf91] - ld [wd0b5], a - ld a, BANK(ItemNames) - ld [wPredefBank], a - call GetName - jr .storeChosenEntry -.pokemonList - ld hl, wPartyCount - ld a, [wListPointer] - cp l ; is it a list of party pokemon or box pokemon? - ld hl, wPartyMonNicks - jr z, .getPokemonName - ld hl, wBoxMonNicks ; box pokemon names -.getPokemonName - ld a, [wWhichPokemon] - call GetPartyMonName -.storeChosenEntry ; store the menu entry that the player chose and return - ld de, wcd6d - call CopyStringToCF4B ; copy name to wcf4b - ld a, CHOSE_MENU_ITEM - ld [wMenuExitMethod], a - ld a, [wCurrentMenuItem] - ld [wChosenMenuItem], a - xor a - ld [hJoy7], a ; joypad state update flag - ld hl, wd730 - res 6, [hl] ; turn on letter printing delay - jp BankswitchBack -.checkOtherKeys ; check B, SELECT, Up, and Down keys - bit 1, a ; was the B button pressed? - jp nz, ExitListMenu ; if so, exit the menu - bit 2, a ; was the select button pressed? - jp nz, HandleItemListSwapping ; if so, allow the player to swap menu entries - ld b, a - bit 7, b ; was Down pressed? - ld hl, wListScrollOffset - jr z, .upPressed -.downPressed - ld a, [hl] - add 3 - ld b, a - ld a, [wListCount] - cp b ; will going down scroll past the Cancel button? - jp c, DisplayListMenuIDLoop - inc [hl] ; if not, go down - jp DisplayListMenuIDLoop -.upPressed - ld a, [hl] - and a - jp z, DisplayListMenuIDLoop - dec [hl] - jp DisplayListMenuIDLoop - -DisplayChooseQuantityMenu:: -; text box dimensions/coordinates for just quantity - coord hl, 15, 9 - lb bc, 1, 3 ; height and width - ld a, [wListMenuID] - cp PRICEDITEMLISTMENU - jr nz, .drawTextBox -; text box dimensions/coordinates for quantity and price - coord hl, 7, 9 - lb bc, 1, 11 ; height and width -.drawTextBox - call TextBoxBorder - coord hl, 16, 10 - ld a, [wListMenuID] - cp PRICEDITEMLISTMENU - jr nz, .printInitialQuantity - coord hl, 8, 10 -.printInitialQuantity - ld de, InitialQuantityText - call PlaceString - xor a - ld [wItemQuantity], a ; initialize current quantity to 0 - jp .incrementQuantity -.waitForKeyPressLoop - call JoypadLowSensitivity - ld a, [hJoyPressed] ; newly pressed buttons - bit 0, a ; was the A button pressed? - jp nz, .buttonAPressed - bit 1, a ; was the B button pressed? - jp nz, .buttonBPressed - bit 6, a ; was Up pressed? - jr nz, .incrementQuantity - bit 7, a ; was Down pressed? - jr nz, .decrementQuantity - jr .waitForKeyPressLoop -.incrementQuantity - ld a, [wMaxItemQuantity] - inc a - ld b, a - ld hl, wItemQuantity ; current quantity - inc [hl] - ld a, [hl] - cp b - jr nz, .handleNewQuantity -; wrap to 1 if the player goes above the max quantity - ld a, 1 - ld [hl], a - jr .handleNewQuantity -.decrementQuantity - ld hl, wItemQuantity ; current quantity - dec [hl] - jr nz, .handleNewQuantity -; wrap to the max quantity if the player goes below 1 - ld a, [wMaxItemQuantity] - ld [hl], a -.handleNewQuantity - coord hl, 17, 10 - ld a, [wListMenuID] - cp PRICEDITEMLISTMENU - jr nz, .printQuantity -.printPrice - ld c, $03 - ld a, [wItemQuantity] - ld b, a - ld hl, hMoney ; total price -; initialize total price to 0 - xor a - ld [hli], a - ld [hli], a - ld [hl], a -.addLoop ; loop to multiply the individual price by the quantity to get the total price - ld de, hMoney + 2 - ld hl, hItemPrice + 2 - push bc - predef AddBCDPredef ; add the individual price to the current sum - pop bc - dec b - jr nz, .addLoop - ld a, [hHalveItemPrices] - and a ; should the price be halved (for selling items)? - jr z, .skipHalvingPrice - xor a - ld [hDivideBCDDivisor], a - ld [hDivideBCDDivisor + 1], a - ld a, $02 - ld [hDivideBCDDivisor + 2], a - predef DivideBCDPredef3 ; halves the price -; store the halved price - ld a, [hDivideBCDQuotient] - ld [hMoney], a - ld a, [hDivideBCDQuotient + 1] - ld [hMoney + 1], a - ld a, [hDivideBCDQuotient + 2] - ld [hMoney + 2], a -.skipHalvingPrice - coord hl, 12, 10 - ld de, SpacesBetweenQuantityAndPriceText - call PlaceString - ld de, hMoney ; total price - ld c, $a3 - call PrintBCDNumber - coord hl, 9, 10 -.printQuantity - ld de, wItemQuantity ; current quantity - lb bc, LEADING_ZEROES | 1, 2 ; 1 byte, 2 digits - call PrintNumber - jp .waitForKeyPressLoop -.buttonAPressed ; the player chose to make the transaction - xor a - ld [wMenuItemToSwap], a ; 0 means no item is currently being swapped - ret -.buttonBPressed ; the player chose to cancel the transaction - xor a - ld [wMenuItemToSwap], a ; 0 means no item is currently being swapped - ld a, $ff - ret - -InitialQuantityText:: - db "×01@" - -SpacesBetweenQuantityAndPriceText:: - db " @" - -ExitListMenu:: - ld a, [wCurrentMenuItem] - ld [wChosenMenuItem], a - ld a, CANCELLED_MENU - ld [wMenuExitMethod], a - ld [wMenuWatchMovingOutOfBounds], a - xor a - ld [hJoy7], a - ld hl, wd730 - res 6, [hl] - call BankswitchBack - xor a - ld [wMenuItemToSwap], a ; 0 means no item is currently being swapped - scf - ret - -PrintListMenuEntries:: - coord hl, 5, 3 - lb bc, 9, 14 - call ClearScreenArea - ld a, [wListPointer] - ld e, a - ld a, [wListPointer + 1] - ld d, a - inc de ; de = beginning of list entries - ld a, [wListScrollOffset] - ld c, a - ld a, [wListMenuID] - cp ITEMLISTMENU - ld a, c - jr nz, .skipMultiplying -; if it's an item menu -; item entries are 2 bytes long, so multiply by 2 - add a - sla c -.skipMultiplying - add e - ld e, a - jr nc, .noCarry - inc d -.noCarry - coord hl, 6, 4 ; coordinates of first list entry name - ld b, 4 ; print 4 names -.loop - ld a, b - ld [wWhichPokemon], a - ld a, [de] - ld [wd11e], a - cp $ff - jp z, .printCancelMenuItem - push bc - push de - push hl - push hl - push de - ld a, [wListMenuID] - and a - jr z, .pokemonPCMenu - cp MOVESLISTMENU - jr z, .movesMenu -.itemMenu - call GetItemName - jr .placeNameString -.pokemonPCMenu - push hl - ld hl, wPartyCount - ld a, [wListPointer] - cp l ; is it a list of party pokemon or box pokemon? - ld hl, wPartyMonNicks - jr z, .getPokemonName - ld hl, wBoxMonNicks ; box pokemon names -.getPokemonName - ld a, [wWhichPokemon] - ld b, a - ld a, 4 - sub b - ld b, a - ld a, [wListScrollOffset] - add b - call GetPartyMonName - pop hl - jr .placeNameString -.movesMenu - call GetMoveName -.placeNameString - call PlaceString - pop de - pop hl - ld a, [wPrintItemPrices] - and a ; should prices be printed? - jr z, .skipPrintingItemPrice -.printItemPrice - push hl - ld a, [de] - ld de, ItemPrices - ld [wcf91], a - call GetItemPrice ; get price - pop hl - ld bc, SCREEN_WIDTH + 5 ; 1 row down and 5 columns right - add hl, bc - ld c, $a3 ; no leading zeroes, right-aligned, print currency symbol, 3 bytes - call PrintBCDNumber -.skipPrintingItemPrice - ld a, [wListMenuID] - and a - jr nz, .skipPrintingPokemonLevel -.printPokemonLevel - ld a, [wd11e] - push af - push hl - ld hl, wPartyCount - ld a, [wListPointer] - cp l ; is it a list of party pokemon or box pokemon? - ld a, PLAYER_PARTY_DATA - jr z, .next - ld a, BOX_DATA -.next - ld [wMonDataLocation], a - ld hl, wWhichPokemon - ld a, [hl] - ld b, a - ld a, $04 - sub b - ld b, a - ld a, [wListScrollOffset] - add b - ld [hl], a - call LoadMonData - ld a, [wMonDataLocation] - and a ; is it a list of party pokemon or box pokemon? - jr z, .skipCopyingLevel -.copyLevel - ld a, [wLoadedMonBoxLevel] - ld [wLoadedMonLevel], a -.skipCopyingLevel - pop hl - ld bc, $001c - add hl, bc - call PrintLevel - pop af - ld [wd11e], a -.skipPrintingPokemonLevel - pop hl - pop de - inc de - ld a, [wListMenuID] - cp ITEMLISTMENU - jr nz, .nextListEntry -.printItemQuantity - ld a, [wd11e] - ld [wcf91], a - call IsKeyItem ; check if item is unsellable - ld a, [wIsKeyItem] - and a ; is the item unsellable? - jr nz, .skipPrintingItemQuantity ; if so, don't print the quantity - push hl - ld bc, SCREEN_WIDTH + 8 ; 1 row down and 8 columns right - add hl, bc - ld a, "×" - ld [hli], a - ld a, [wd11e] - push af - ld a, [de] - ld [wMaxItemQuantity], a - push de - ld de, wd11e - ld [de], a - lb bc, 1, 2 - call PrintNumber - pop de - pop af - ld [wd11e], a - pop hl -.skipPrintingItemQuantity - inc de - pop bc - inc c - push bc - inc c - ld a, [wMenuItemToSwap] ; ID of item chosen for swapping (counts from 1) - and a ; is an item being swapped? - jr z, .nextListEntry - add a - cp c ; is it this item? - jr nz, .nextListEntry - dec hl - ld a, $ec ; unfilled right arrow menu cursor to indicate an item being swapped - ld [hli], a -.nextListEntry - ld bc, 2 * SCREEN_WIDTH ; 2 rows - add hl, bc - pop bc - inc c - dec b - jp nz, .loop - ld bc, -8 - add hl, bc - ld a, "▼" - ld [hl], a - ret -.printCancelMenuItem - ld de, ListMenuCancelText - jp PlaceString - -ListMenuCancelText:: - db "CANCEL@" - -GetMonName:: - push hl - ld a, [H_LOADEDROMBANK] - push af - ld a, BANK(MonsterNames) - ld [H_LOADEDROMBANK], a - ld [MBC1RomBank], a - ld a, [wd11e] - dec a - ld hl, MonsterNames - ld c, 10 - ld b, 0 - call AddNTimes - ld de, wcd6d - push de - ld bc, 10 - call CopyData - ld hl, wcd6d + 10 - ld [hl], "@" - pop de - pop af - ld [H_LOADEDROMBANK], a - ld [MBC1RomBank], a - pop hl - ret - -GetItemName:: -; given an item ID at [wd11e], store the name of the item into a string -; starting at wcd6d - push hl - push bc - ld a, [wd11e] - cp HM_01 ; is this a TM/HM? - jr nc, .Machine - - ld [wd0b5], a - ld a, ITEM_NAME - ld [wNameListType], a - ld a, BANK(ItemNames) - ld [wPredefBank], a - call GetName - jr .Finish - -.Machine - call GetMachineName -.Finish - ld de, wcd6d ; pointer to where item name is stored in RAM - pop bc - pop hl - ret - -GetMachineName:: -; copies the name of the TM/HM in [wd11e] to wcd6d - push hl - push de - push bc - ld a, [wd11e] - push af - cp TM_01 ; is this a TM? [not HM] - jr nc, .WriteTM -; if HM, then write "HM" and add 5 to the item ID, so we can reuse the -; TM printing code - add 5 - ld [wd11e], a - ld hl, HiddenPrefix ; points to "HM" - ld bc, 2 - jr .WriteMachinePrefix -.WriteTM - ld hl, TechnicalPrefix ; points to "TM" - ld bc, 2 -.WriteMachinePrefix - ld de, wcd6d - call CopyData - -; now get the machine number and convert it to text - ld a, [wd11e] - sub TM_01 - 1 - ld b, "0" -.FirstDigit - sub 10 - jr c, .SecondDigit - inc b - jr .FirstDigit -.SecondDigit - add 10 - push af - ld a, b - ld [de], a - inc de - pop af - ld b, "0" - add b - ld [de], a - inc de - ld a, "@" - ld [de], a - pop af - ld [wd11e], a - pop bc - pop de - pop hl - ret - -TechnicalPrefix:: - db "TM" -HiddenPrefix:: - db "HM" - -; sets carry if item is HM, clears carry if item is not HM -; Input: a = item ID -IsItemHM:: - cp HM_01 - jr c, .notHM - cp TM_01 - ret -.notHM - and a - ret - -; sets carry if move is an HM, clears carry if move is not an HM -; Input: a = move ID -IsMoveHM:: - ld hl, HMMoves - ld de, 1 - jp IsInArray - -HMMoves:: - db CUT, FLY, SURF, STRENGTH, FLASH - db $ff ; terminator - -GetMoveName:: - push hl - ld a, MOVE_NAME - ld [wNameListType], a - ld a, [wd11e] - ld [wd0b5], a - ld a, BANK(MoveNames) - ld [wPredefBank], a - call GetName - ld de, wcd6d ; pointer to where move name is stored in RAM - pop hl - ret - -; reloads text box tile patterns, current map view, and tileset tile patterns -ReloadMapData:: - ld a, [H_LOADEDROMBANK] - push af - ld a, [wCurMap] - call SwitchToMapRomBank - call DisableLCD - call LoadTextBoxTilePatterns - call LoadCurrentMapView - call LoadTilesetTilePatternData - call EnableLCD - pop af - call BankswitchCommon - ret - -; reloads tileset tile patterns -ReloadTilesetTilePatterns:: - ld a, [H_LOADEDROMBANK] - push af - ld a, [wCurMap] - call SwitchToMapRomBank - call DisableLCD - call LoadTilesetTilePatternData - call EnableLCD - pop af - call BankswitchCommon - ret - -; shows the town map and lets the player choose a destination to fly to -ChooseFlyDestination:: - ld hl, wd72e - res 4, [hl] - jpba LoadTownMap_Fly - -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 - ld [rSB], a - ld a, $1 - ld [rSC], a - ld a, START_TRANSFER_INTERNAL_CLOCK - ld [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 - -; uses an item -; UseItem is used with dummy items to perform certain other functions as well -; INPUT: -; [wcf91] = item ID -; OUTPUT: -; [wActionResultOrTookBattleTurn] = success -; 00: unsuccessful -; 01: successful -; 02: not able to be used right now, no extra menu displayed (only certain items use this) -UseItem:: - jpba UseItem_ - -; confirms the item toss and then tosses the item -; INPUT: -; hl = address of inventory (either wNumBagItems or wNumBoxItems) -; [wcf91] = item ID -; [wWhichPokemon] = index of item within inventory -; [wItemQuantity] = quantity to toss -; OUTPUT: -; clears carry flag if the item is tossed, sets carry flag if not -TossItem:: - ld a, [H_LOADEDROMBANK] - push af - ld a, BANK(TossItem_) - ld [H_LOADEDROMBANK], a - ld [MBC1RomBank], a - call TossItem_ - pop de - ld a, d - ld [H_LOADEDROMBANK], a - ld [MBC1RomBank], a - ret - -; checks if an item is a key item -; INPUT: -; [wcf91] = item ID -; OUTPUT: -; [wIsKeyItem] = result -; 00: item is not key item -; 01: item is key item -IsKeyItem:: - push hl - push de - push bc - callba IsKeyItem_ - pop bc - pop de - pop hl - ret - -; function to draw various text boxes -; INPUT: -; [wTextBoxID] = text box ID -; b, c = y, x cursor position (TWO_OPTION_MENU only) -DisplayTextBoxID:: - homecall_sf DisplayTextBoxID_ - ret + text_far _PokemonText + text_end + +INCLUDE "home/text_script.asm" +INCLUDE "home/start_menu.asm" +INCLUDE "home/count_set_bits.asm" +INCLUDE "home/inventory.asm" +INCLUDE "home/list_menu.asm" +INCLUDE "home/names.asm" +INCLUDE "home/reload_tiles.asm" +INCLUDE "home/item.asm" +INCLUDE "home/textbox.asm" UpdateGBCPal_BGP:: push af - ld a, [hGBC] + ldh a, [hGBC] and a jr z, .notGBC push bc push de push hl - ld a, [rBGP] + ldh a, [rBGP] ld b, a ld a, [wLastBGP] cp b jr z, .noChangeInBGP - callba _UpdateGBCPal_BGP + farcall _UpdateGBCPal_BGP .noChangeInBGP pop hl pop de @@ -2231,13 +137,13 @@ UpdateGBCPal_BGP:: UpdateGBCPal_OBP0:: push af - ld a, [hGBC] + ldh a, [hGBC] and a jr z, .notGBC push bc push de push hl - ld a, [rOBP0] + ldh a, [rOBP0] ld b, a ld a, [wLastOBP0] cp b @@ -2256,13 +162,13 @@ UpdateGBCPal_OBP0:: UpdateGBCPal_OBP1:: push af - ld a, [hGBC] + ldh a, [hGBC] and a jr z, .notGBC push bc push de push hl - ld a, [rOBP1] + ldh a, [rOBP1] ld b, a ld a, [wLastOBP1] cp b @@ -2280,7 +186,7 @@ UpdateGBCPal_OBP1:: ret Func_3082:: - ld a, [H_LOADEDROMBANK] + ldh a, [hLoadedROMBank] push af call FadeOutAudio callbs Music_DoLowHealthAlarm @@ -2289,2064 +195,32 @@ Func_3082:: call BankswitchCommon ret -; not zero if an NPC movement script is running, the player character is -; automatically stepping down from a door, or joypad states are being simulated -IsPlayerCharacterBeingControlledByGame:: - ld a, [wNPCMovementScriptPointerTableNum] - and a - ret nz - ld a, [wd736] - bit 1, a ; currently stepping down from door bit - ret nz - ld a, [wd730] - and $80 - ret - -RunNPCMovementScript:: - ld hl, wd736 - bit 0, [hl] - res 0, [hl] - jr nz, .playerStepOutFromDoor - ld a, [wNPCMovementScriptPointerTableNum] - and a - ret z - dec a - add a - ld d, 0 - ld e, a - ld hl, .NPCMovementScriptPointerTables - add hl, de - ld a, [hli] - ld h, [hl] - ld l, a - ld a, [H_LOADEDROMBANK] - push af - ld a, [wNPCMovementScriptBank] - call BankswitchCommon - ld a, [wNPCMovementScriptFunctionNum] - call CallFunctionInTable - pop af - call BankswitchCommon - ret - -.NPCMovementScriptPointerTables - dw PalletMovementScriptPointerTable - dw PewterMuseumGuyMovementScriptPointerTable - dw PewterGymGuyMovementScriptPointerTable -.playerStepOutFromDoor - jpba PlayerStepOutFromDoor - -EndNPCMovementScript:: - jpba _EndNPCMovementScript - -EmptyFunc2:: - ret - -; stores hl in [wTrainerHeaderPtr] -StoreTrainerHeaderPointer:: - ld a, h - ld [wTrainerHeaderPtr], a - ld a, l - ld [wTrainerHeaderPtr + 1], a - ret - -; executes the current map script from the function pointer array provided in hl. -; a: map script index to execute (unless overridden by [wd733] bit 4) -ExecuteCurMapScriptInTable:: - push af - push de - call StoreTrainerHeaderPointer - pop hl - pop af - push hl - ld hl, wFlags_D733 - bit 4, [hl] - res 4, [hl] - jr z, .useProvidedIndex ; test if map script index was overridden manually - ld a, [wCurMapScript] -.useProvidedIndex - pop hl - ld [wCurMapScript], a - call CallFunctionInTable - ld a, [wCurMapScript] - ret - -LoadGymLeaderAndCityName:: - push de - ld de, wGymCityName - ld bc, $11 - call CopyData ; load city name - pop hl - ld de, wGymLeaderName - ld bc, NAME_LENGTH - jp CopyData ; load gym leader name - -; reads specific information from trainer header (pointed to at wTrainerHeaderPtr) -; a: offset in header data -; 0 -> flag's bit (into wTrainerHeaderFlagBit) -; 2 -> flag's byte ptr (into hl) -; 4 -> before battle text (into hl) -; 6 -> after battle text (into hl) -; 8 -> end battle text (into hl) -ReadTrainerHeaderInfo:: - push de - push af - ld d, $0 - ld e, a - ld hl, wTrainerHeaderPtr - ld a, [hli] - ld l, [hl] - ld h, a - add hl, de - pop af - and a - jr nz, .nonZeroOffset - ld a, [hl] - ld [wTrainerHeaderFlagBit], a ; store flag's bit - jr .done -.nonZeroOffset - cp $2 - jr z, .readPointer ; read flag's byte ptr - cp $4 - jr z, .readPointer ; read before battle text - cp $6 - jr z, .readPointer ; read after battle text - cp $8 - jr z, .readPointer ; read end battle text - cp $a - jr nz, .done - ld a, [hli] ; read end battle text (2) but override the result afterwards (XXX why, bug?) - ld d, [hl] - ld e, a - jr .done -.readPointer - ld a, [hli] - ld h, [hl] - ld l, a -.done - pop de - ret - -TrainerFlagAction:: - predef_jump FlagActionPredef - -TalkToTrainer:: - call StoreTrainerHeaderPointer - xor a - call ReadTrainerHeaderInfo ; read flag's bit - ld a, $2 - call ReadTrainerHeaderInfo ; read flag's byte ptr - ld a, [wTrainerHeaderFlagBit] - ld c, a - ld b, FLAG_TEST - call TrainerFlagAction ; read trainer's flag - ld a, c - and a - jr z, .trainerNotYetFought ; test trainer's flag - ld a, $6 - call ReadTrainerHeaderInfo ; print after battle text - jp PrintText -.trainerNotYetFought - ld a, $4 - call ReadTrainerHeaderInfo ; print before battle text - call PrintText - ld a, $a - call ReadTrainerHeaderInfo ; (?) does nothing apparently (maybe bug in ReadTrainerHeaderInfo) - push de - ld a, $8 - call ReadTrainerHeaderInfo ; read end battle text - pop de - call SaveEndBattleTextPointers - ld hl, wFlags_D733 - set 4, [hl] ; activate map script index override (index is set below) - ld hl, wFlags_0xcd60 - bit 0, [hl] ; test if player is already engaging the trainer (because the trainer saw the player) - ret nz -; if the player talked to the trainer of his own volition - call EngageMapTrainer - ld hl, wCurMapScript - inc [hl] ; increment map script index before StartTrainerBattle increments it again (next script function is usually EndTrainerBattle) - jp StartTrainerBattle - -; checks if any trainers are seeing the player and wanting to fight -CheckFightingMapTrainers:: - call CheckForEngagingTrainers - ld a, [wSpriteIndex] - cp $ff - jr nz, .trainerEngaging - xor a - ld [wSpriteIndex], a - ld [wTrainerHeaderFlagBit], a - ret -.trainerEngaging - ld hl, wFlags_D733 - set 3, [hl] - ld [wEmotionBubbleSpriteIndex], a - xor a ; EXCLAMATION_BUBBLE - ld [wWhichEmotionBubble], a - predef EmotionBubble - ld a, D_RIGHT | D_LEFT | D_UP | D_DOWN - ld [wJoyIgnore], a - xor a - ld [hJoyHeld], a - call TrainerWalkUpToPlayer_Bank0 - ld hl, wCurMapScript - inc [hl] ; increment map script index (next script function is usually DisplayEnemyTrainerTextAndStartBattle) - ret - -; display the before battle text after the enemy trainer has walked up to the player's sprite -DisplayEnemyTrainerTextAndStartBattle:: - ld a, [wd730] - and $1 - ret nz ; return if the enemy trainer hasn't finished walking to the player's sprite - ld [wJoyIgnore], a - ld a, [wSpriteIndex] - ld [hSpriteIndexOrTextID], a - call DisplayTextID - ; fall through - -StartTrainerBattle:: - xor a - ld [wJoyIgnore], a - call InitBattleEnemyParameters - ld hl, wd72d - set 6, [hl] - set 7, [hl] - ld hl, wd72e - set 1, [hl] - ld hl, wCurMapScript - inc [hl] ; increment map script index (next script function is usually EndTrainerBattle) - ret - -EndTrainerBattle:: - ld hl, wCurrentMapScriptFlags - set 5, [hl] - set 6, [hl] - ld hl, wd72d - res 7, [hl] - ld hl, wFlags_0xcd60 - res 0, [hl] ; player is no longer engaged by any trainer - ld a, [wIsInBattle] - cp $ff - jp z, ResetButtonPressedAndMapScript - ld a, $2 - call ReadTrainerHeaderInfo - ld a, [wTrainerHeaderFlagBit] - ld c, a - ld b, FLAG_SET - call TrainerFlagAction ; flag trainer as fought - ld a, [wEnemyMonOrTrainerClass] - cp OPP_ID_OFFSET - jr nc, .skipRemoveSprite ; test if trainer was fought (in that case skip removing the corresponding sprite) - ld hl, wMissableObjectList - ld de, $2 - ld a, [wSpriteIndex] - call IsInArray ; search for sprite ID - inc hl - ld a, [hl] - ld [wMissableObjectIndex], a ; load corresponding missable object index and remove it - predef HideObject -.skipRemoveSprite - ld hl, wd730 - bit 4, [hl] - res 4, [hl] - ret nz - -ResetButtonPressedAndMapScript:: - xor a - ld [wJoyIgnore], a - ld [hJoyHeld], a - ld [hJoyPressed], a - ld [hJoyReleased], a - ld [wCurMapScript], a ; reset battle status - ret - -; calls TrainerWalkUpToPlayer -TrainerWalkUpToPlayer_Bank0:: - jpba TrainerWalkUpToPlayer - -; sets opponent type and mon set/lvl based on the engaging trainer data -InitBattleEnemyParameters:: - ld a, [wEngagedTrainerClass] - ld [wCurOpponent], a - ld [wEnemyMonOrTrainerClass], a - cp OPP_ID_OFFSET - ld a, [wEngagedTrainerSet] - jr c, .noTrainer - ld [wTrainerNo], a - ret -.noTrainer - ld [wCurEnemyLVL], a - ret - -GetSpritePosition1:: - ld hl, _GetSpritePosition1 - jr SpritePositionBankswitch - -GetSpritePosition2:: - ld hl, _GetSpritePosition2 - jr SpritePositionBankswitch - -SetSpritePosition1:: - ld hl, _SetSpritePosition1 - jr SpritePositionBankswitch - -SetSpritePosition2:: - ld hl, _SetSpritePosition2 -SpritePositionBankswitch:: - ld b, BANK(_GetSpritePosition1) ; BANK(_GetSpritePosition2), BANK(_SetSpritePosition1), BANK(_SetSpritePosition2) - jp Bankswitch ; indirect jump to one of the four functions - -CheckForEngagingTrainers:: - xor a - call ReadTrainerHeaderInfo ; read trainer flag's bit (unused) - ld d, h ; store trainer header address in de - ld e, l -.trainerLoop - call StoreTrainerHeaderPointer ; set trainer header pointer to current trainer - ld a, [de] - ld [wSpriteIndex], a ; store trainer flag's bit - ld [wTrainerHeaderFlagBit], a - cp $ff - ret z - ld a, $2 - call ReadTrainerHeaderInfo ; read trainer flag's byte ptr - ld b, FLAG_TEST - ld a, [wTrainerHeaderFlagBit] - ld c, a - call TrainerFlagAction ; read trainer flag - ld a, c - and a ; has the trainer already been defeated? - jr nz, .continue - push hl - push de - push hl - xor a - call ReadTrainerHeaderInfo ; get trainer header pointer - inc hl - ld a, [hl] ; read trainer engage distance - pop hl - ld [wTrainerEngageDistance], a - ld a, [wSpriteIndex] - swap a - ld [wTrainerSpriteOffset], a - predef TrainerEngage - pop de - pop hl - ld a, [wTrainerSpriteOffset] - and a - ret nz ; break if the trainer is engaging -.continue - ld hl, $c - add hl, de - ld d, h - ld e, l - jr .trainerLoop - -; hl = text if the player wins -; de = text if the player loses -SaveEndBattleTextPointers:: - ld a, [H_LOADEDROMBANK] - ld [wEndBattleTextRomBank], a - ld a, h - ld [wEndBattleWinTextPointer], a - ld a, l - ld [wEndBattleWinTextPointer + 1], a - ld a, d - ld [wEndBattleLoseTextPointer], a - ld a, e - ld [wEndBattleLoseTextPointer + 1], a - ret - -; loads data of some trainer on the current map and plays pre-battle music -; [wSpriteIndex]: sprite ID of trainer who is engaged -EngageMapTrainer:: - ld hl, wMapSpriteExtraData - ld d, $0 - ld a, [wSpriteIndex] - dec a - add a - ld e, a - add hl, de ; seek to engaged trainer data - ld a, [hli] ; load trainer class - ld [wEngagedTrainerClass], a - ld a, [hl] ; load trainer mon set - ld [wEngagedTrainerSet], a - jp PlayTrainerMusic - -PrintEndBattleText:: - push hl - ld hl, wd72d - bit 7, [hl] - res 7, [hl] - pop hl - ret z - ld a, [H_LOADEDROMBANK] - push af - ld a, [wEndBattleTextRomBank] - ld [H_LOADEDROMBANK], a - ld [MBC1RomBank], a - push hl - callba SaveTrainerName - ld hl, TrainerEndBattleText - call PrintText - pop hl - pop af - ld [H_LOADEDROMBANK], a - ld [MBC1RomBank], a - callba FreezeEnemyTrainerSprite - jp WaitForSoundToFinish - -GetSavedEndBattleTextPointer:: - ld a, [wBattleResult] - and a -; won battle - jr nz, .lostBattle - ld a, [wEndBattleWinTextPointer] - ld h, a - ld a, [wEndBattleWinTextPointer + 1] - ld l, a - ret -.lostBattle - ld a, [wEndBattleLoseTextPointer] - ld h, a - ld a, [wEndBattleLoseTextPointer + 1] - ld l, a - ret - -TrainerEndBattleText:: - TX_FAR _TrainerNameText - TX_ASM - call GetSavedEndBattleTextPointer - call TextCommandProcessor - jp TextScriptEnd - -PlayTrainerMusic:: - ld a, [wEngagedTrainerClass] - cp OPP_SONY1 - ret z - cp OPP_SONY2 - ret z - cp OPP_SONY3 - ret z - ld a, [wGymLeaderNo] - and a - ret nz - xor a - ld [wAudioFadeOutControl], a - call StopAllMusic ; stop music - ld a, BANK(Music_MeetEvilTrainer) - ld [wAudioROMBank], a - ld [wAudioSavedROMBank], a - ld a, [wEngagedTrainerClass] - ld b, a - ld hl, EvilTrainerList -.evilTrainerListLoop - ld a, [hli] - cp $ff - jr z, .noEvilTrainer - cp b - jr nz, .evilTrainerListLoop - ld a, MUSIC_MEET_EVIL_TRAINER - jr .PlaySound -.noEvilTrainer - ld hl, FemaleTrainerList -.femaleTrainerListLoop - ld a, [hli] - cp $ff - jr z, .maleTrainer - cp b - jr nz, .femaleTrainerListLoop - ld a, MUSIC_MEET_FEMALE_TRAINER - jr .PlaySound -.maleTrainer - ld a, MUSIC_MEET_MALE_TRAINER -.PlaySound - ld [wNewSoundID], a - jp PlaySound - -INCLUDE "data/trainer_types.asm" - -; checks if the player's coordinates match an arrow movement tile's coordinates -; and if so, decodes the RLE movement data -; b = player Y -; c = player X -DecodeArrowMovementRLE:: - ld a, [hli] - cp $ff - ret z ; no match in the list - cp b - jr nz, .nextArrowMovementTileEntry1 - ld a, [hli] - cp c - jr nz, .nextArrowMovementTileEntry2 - ld a, [hli] - ld d, [hl] - ld e, a - ld hl, wSimulatedJoypadStatesEnd - call DecodeRLEList - dec a - ld [wSimulatedJoypadStatesIndex], a - ret -.nextArrowMovementTileEntry1 - inc hl -.nextArrowMovementTileEntry2 - inc hl - inc hl - jr DecodeArrowMovementRLE - -FuncTX_ItemStoragePC:: - call SaveScreenTilesToBuffer2 - ld b, BANK(PlayerPC) - ld hl, PlayerPC - jr bankswitchAndContinue - -FuncTX_BillsPC:: - call SaveScreenTilesToBuffer2 - ld b, BANK(BillsPC_) - ld hl, BillsPC_ - jr bankswitchAndContinue - -FuncTX_GameCornerPrizeMenu:: -; XXX find a better name for this function -; special_F7 - ld b, BANK(CeladonPrizeMenu) - ld hl, CeladonPrizeMenu -bankswitchAndContinue:: - call Bankswitch - jp HoldTextDisplayOpen ; continue to main text-engine function - -FuncTX_PokemonCenterPC:: - ld b, BANK(ActivatePC) - ld hl, ActivatePC - jr bankswitchAndContinue - -StartSimulatingJoypadStates:: - xor a - ld [wOverrideSimulatedJoypadStatesMask], a - ld [wSpriteStateData2 + $06], a ; player's sprite movement byte 1 - ld hl, wd730 - set 7, [hl] - ret - -IsItemInBag:: -; given an item_id in b -; set zero flag if item isn't in player's bag -; else reset zero flag -; related to Pokémon Tower and ghosts - predef GetQuantityOfItemInBag - ld a, b - 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 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 - callab IsStarterPikachuInOurParty - pop bc - pop hl - ret nc - ld a, [wd472] - set 7, a - ld [wd472], a - ret - -DisplayPokedex:: - ld [wd11e], a - jpba _DisplayPokedex - -SetSpriteFacingDirectionAndDelay:: - call SetSpriteFacingDirection - ld c, 6 - jp DelayFrames - -SetSpriteFacingDirection:: - ld a, $9 - ld [H_SPRITEDATAOFFSET], a - call GetPointerWithinSpriteStateData1 - ld a, [hSpriteFacingDirection] - ld [hl], a - ret - -SetSpriteImageIndexAfterSettingFacingDirection:: - ld de, -7 - add hl, de - ld [hl], a - ret - -SpriteFunc_34a1:: - ld a, [H_SPRITEINDEX] - swap a - add $e - ld l, a - ld h, $c2 - ld c, [hl] - dec c - swap c - ld a, [$ff8d] - add c - ld c, a - ld a, [$ff8c] - 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 -; OUTPUT: -; [wCoordIndex] = if there is match, the matching array index -; sets carry if the coordinates are in the array, clears carry if not -ArePlayerCoordsInArray:: - ld a, [wYCoord] - ld b, a - ld a, [wXCoord] - ld c, a - ; fallthrough - -CheckCoords:: - xor a - ld [wCoordIndex], a -.loop - ld a, [hli] - cp $ff ; reached terminator? - jr z, .notInArray - push hl - ld hl, wCoordIndex - inc [hl] - pop hl -.compareYCoord - cp b - jr z, .compareXCoord - inc hl - jr .loop -.compareXCoord - ld a, [hli] - cp c - jr nz, .loop -.inArray - scf - ret -.notInArray - and a - ret - -; tests if a boulder's coordinates are in a specified array -; INPUT: -; hl = address of array -; [H_SPRITEINDEX] = index of boulder sprite -; OUTPUT: -; [wCoordIndex] = if there is match, the matching array index -; sets carry if the coordinates are in the array, clears carry if not -CheckBoulderCoords:: - push hl - ld hl, wSpriteStateData2 + $04 - ld a, [H_SPRITEINDEX] - swap a - ld d, $0 - ld e, a - add hl, de - ld a, [hli] - sub $4 ; because sprite coordinates are offset by 4 - ld b, a - ld a, [hl] - sub $4 ; because sprite coordinates are offset by 4 - ld c, a - pop hl - jp CheckCoords - -GetPointerWithinSpriteStateData1:: - ld h, $c1 - jr _GetPointerWithinSpriteStateData - -GetPointerWithinSpriteStateData2:: - ld h, $c2 - -_GetPointerWithinSpriteStateData: - ld a, [H_SPRITEDATAOFFSET] - ld b, a - ld a, [H_SPRITEINDEX] - swap a - add b - ld l, a - ret - -; decodes a $ff-terminated RLEncoded list -; each entry is a pair of bytes <byte value> <repetitions> -; the final $ff will be replicated in the output list and a contains the number of bytes written -; de: input list -; hl: output list -DecodeRLEList:: - xor a - ld [wRLEByteCount], a ; count written bytes here -.listLoop - ld a, [de] - cp $ff - jr z, .endOfList - ld [hRLEByteValue], a ; store byte value to be written - inc de - ld a, [de] - ld b, $0 - ld c, a ; number of bytes to be written - ld a, [wRLEByteCount] - add c - ld [wRLEByteCount], a ; update total number of written bytes - ld a, [hRLEByteValue] - call FillMemory ; write a c-times to output - inc de - jr .listLoop -.endOfList - ld a, $ff - ld [hl], a ; write final $ff - ld a, [wRLEByteCount] - inc a ; include sentinel in counting - ret - -; sets movement byte 1 for sprite [H_SPRITEINDEX] to $FE and byte 2 to [hSpriteMovementByte2] -SetSpriteMovementBytesToFE:: - push hl - call GetSpriteMovementByte1Pointer - ld [hl], $fe - call GetSpriteMovementByte2Pointer - ld a, [hSpriteMovementByte2] - ld [hl], a - pop hl - ret - -; sets both movement bytes for sprite [H_SPRITEINDEX] to $FF -SetSpriteMovementBytesToFF:: - push hl - call GetSpriteMovementByte1Pointer - ld [hl], $FF - call GetSpriteMovementByte2Pointer - ld [hl], $FF ; prevent person from walking? - pop hl - ret - -; returns the sprite movement byte 1 pointer for sprite [H_SPRITEINDEX] in hl -GetSpriteMovementByte1Pointer:: - ld h, $C2 - ld a, [H_SPRITEINDEX] - swap a - add 6 - ld l, a - ret - -; returns the sprite movement byte 2 pointer for sprite [H_SPRITEINDEX] in hl -GetSpriteMovementByte2Pointer:: - push de - ld hl, wMapSpriteData - ld a, [H_SPRITEINDEX] - dec a - add a - ld e, a - ld d, 0 - add hl, de - pop de - ret - -GetTrainerInformation:: - call GetTrainerName - ld a, [wLinkState] - and a - jr nz, .linkBattle - ld a, BANK(TrainerPicAndMoneyPointers) - call BankswitchHome - ld a, [wTrainerClass] - dec a - ld hl, TrainerPicAndMoneyPointers - ld bc, $5 - call AddNTimes - ld de, wTrainerPicPointer - ld a, [hli] - ld [de], a - inc de - ld a, [hli] - ld [de], a - ld de, wTrainerBaseMoney - ld a, [hli] - ld [de], a - inc de - ld a, [hli] - ld [de], a - call IsFightingJessieJames - jp BankswitchBack -.linkBattle - ld hl, wTrainerPicPointer - ld de, RedPicFront - ld [hl], e - inc hl - 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:: - jpba GetTrainerName_ - -HasEnoughMoney:: -; Check if the player has at least as much -; money as the 3-byte BCD value at hMoney. - ld de, wPlayerMoney - ld hl, hMoney - ld c, 3 - jp StringCmp - -HasEnoughCoins:: -; Check if the player has at least as many -; coins as the 2-byte BCD value at hCoins. - ld de, wPlayerCoins - ld hl, hCoins - ld c, 2 - jp StringCmp - - -BankswitchHome:: -; switches to bank # in a -; Only use this when in the home bank! - ld [wBankswitchHomeTemp], a - ld a, [H_LOADEDROMBANK] - ld [wBankswitchHomeSavedROMBank], a - ld a, [wBankswitchHomeTemp] - call BankswitchCommon - ret - -BankswitchBack:: -; returns from BankswitchHome - ld a, [wBankswitchHomeSavedROMBank] - call BankswitchCommon - ret - -; displays yes/no choice -; yes -> set carry -YesNoChoice:: - call SaveScreenTilesToBuffer1 - call InitYesNoTextBoxParameters - jr DisplayYesNoChoice - -Func_35f7:: - ld a, TWO_OPTION_MENU - ld [wTextBoxID], a - call InitYesNoTextBoxParameters - jp DisplayTextBoxID - -InitYesNoTextBoxParameters:: - xor a ; YES_NO_MENU - ld [wTwoOptionMenuID], a - coord hl, 14, 7 - ld bc, $80f - ret - -YesNoChoicePokeCenter:: - call SaveScreenTilesToBuffer1 - ld a, HEAL_CANCEL_MENU - ld [wTwoOptionMenuID], a - coord hl, 11, 6 - lb bc, 8, 12 - jr DisplayYesNoChoice - -WideYesNoChoice:: ; unused - call SaveScreenTilesToBuffer1 - ld a, WIDE_YES_NO_MENU - ld [wTwoOptionMenuID], a - coord hl, 12, 7 - lb bc, 8, 13 - -DisplayYesNoChoice:: - ld a, TWO_OPTION_MENU - ld [wTextBoxID], a - call DisplayTextBoxID - jp LoadScreenTilesFromBuffer1 - -; calculates the difference |a-b|, setting carry flag if a<b -CalcDifference:: - sub b - ret nc - cpl - add $1 - scf - ret - -MoveSprite:: -; move the sprite [H_SPRITEINDEX] with the movement pointed to by de -; actually only copies the movement data to wNPCMovementDirections for later - call SetSpriteMovementBytesToFF -MoveSprite_:: - push hl - push bc - call GetSpriteMovementByte1Pointer - xor a - ld [hl], a - ld hl, wNPCMovementDirections - ld c, 0 - -.loop - ld a, [de] - ld [hli], a - inc de - inc c - cp $FF ; have we reached the end of the movement data? - jr nz, .loop - - ld a, c - ld [wNPCNumScriptedSteps], a ; number of steps taken - - pop bc - ld hl, wd730 - set 0, [hl] - pop hl - xor a - ld [wOverrideSimulatedJoypadStatesMask], a - ld [wSimulatedJoypadStatesEnd], a - dec a - ld [wJoyIgnore], a - ld [wWastedByteCD3A], a - ret - -; divides [hDividend2] by [hDivisor2] and stores the quotient in [hQuotient2] -DivideBytes:: - push hl - ld hl, hQuotient2 - xor a - ld [hld], a - ld a, [hld] - and a - jr z, .done - ld a, [hli] -.loop - sub [hl] - jr c, .done - inc hl - inc [hl] - dec hl - jr .loop -.done - pop hl - ret - - -LoadFontTilePatterns:: - ld a, [rLCDC] - bit 7, a ; is the LCD enabled? - jr nz, .on -.off - ld hl, FontGraphics - ld de, vFont - ld bc, FontGraphicsEnd - FontGraphics - ld a, BANK(FontGraphics) - jp FarCopyDataDouble ; if LCD is off, transfer all at once -.on - ld de, FontGraphics - ld hl, vFont - lb bc, BANK(FontGraphics), (FontGraphicsEnd - FontGraphics) / $8 - jp CopyVideoDataDouble ; if LCD is on, transfer during V-blank - -LoadTextBoxTilePatterns:: - ld a, [rLCDC] - bit 7, a ; is the LCD enabled? - jr nz, .on -.off - ld hl, TextBoxGraphics - ld de, vChars2 + $600 - ld bc, TextBoxGraphicsEnd - TextBoxGraphics - ld a, BANK(TextBoxGraphics) - jp FarCopyData ; if LCD is off, transfer all at once -.on - ld de, TextBoxGraphics - ld hl, vChars2 + $600 - lb bc, BANK(TextBoxGraphics), (TextBoxGraphicsEnd - TextBoxGraphics) / $10 - jp CopyVideoData ; if LCD is on, transfer during V-blank - -LoadHpBarAndStatusTilePatterns:: - ld a, [rLCDC] - bit 7, a ; is the LCD enabled? - jr nz, .on -.off - ld hl, HpBarAndStatusGraphics - ld de, vChars2 + $620 - ld bc, HpBarAndStatusGraphicsEnd - HpBarAndStatusGraphics - ld a, BANK(HpBarAndStatusGraphics) - jp FarCopyData ; if LCD is off, transfer all at once -.on - ld de, HpBarAndStatusGraphics - ld hl, vChars2 + $620 - lb bc, BANK(HpBarAndStatusGraphics), (HpBarAndStatusGraphicsEnd - HpBarAndStatusGraphics) / $10 - jp CopyVideoData ; if LCD is on, transfer during V-blank - -UncompressSpriteFromDE:: -; Decompress pic at a:de. - ld hl, wSpriteInputPtr - ld [hl], e - inc hl - ld [hl], d - jp UncompressSpriteData - -SaveScreenTilesToBuffer2:: - coord hl, 0, 0 - ld de, wTileMapBackup2 - ld bc, SCREEN_WIDTH * SCREEN_HEIGHT - jp CopyData - -LoadScreenTilesFromBuffer2:: - call LoadScreenTilesFromBuffer2DisableBGTransfer - ld a, 1 - ld [H_AUTOBGTRANSFERENABLED], a - ret - -; loads screen tiles stored in wTileMapBackup2 but leaves H_AUTOBGTRANSFERENABLED disabled -LoadScreenTilesFromBuffer2DisableBGTransfer:: - xor a - ld [H_AUTOBGTRANSFERENABLED], a - ld hl, wTileMapBackup2 - coord de, 0, 0 - ld bc, SCREEN_WIDTH * SCREEN_HEIGHT - jp CopyData - -SaveScreenTilesToBuffer1:: - coord hl, 0, 0 - ld de, wTileMapBackup - ld bc, SCREEN_WIDTH * SCREEN_HEIGHT - jp CopyData - -LoadScreenTilesFromBuffer1:: - xor a - ld [H_AUTOBGTRANSFERENABLED], a - ld hl, wTileMapBackup - coord de, 0, 0 - ld bc, SCREEN_WIDTH * SCREEN_HEIGHT - call CopyData - ld a, 1 - ld [H_AUTOBGTRANSFERENABLED], a - ret - -DelayFrames:: -; wait c frames - call DelayFrame - dec c - jr nz, DelayFrames - ret - -PlaySoundWaitForCurrent:: - push af - call WaitForSoundToFinish - pop af - jp PlaySound - -; Wait for sound to finish playing -WaitForSoundToFinish:: - ld a, [wLowHealthAlarm] - and $80 - ret nz - push hl -.waitLoop - ld hl, wChannelSoundIDs + Ch5 - xor a - or [hl] - inc hl - or [hl] - inc hl - inc hl - or [hl] - and a - jr nz, .waitLoop - pop hl - ret - -NamePointers:: - dw MonsterNames - dw MoveNames - dw UnusedNames - dw ItemNames - dw wPartyMonOT ; player's OT names list - dw wEnemyMonOT ; enemy's OT names list - dw TrainerNames - -GetName:: -; arguments: -; [wd0b5] = which name -; [wNameListType] = which list -; [wPredefBank] = bank of list -; -; returns pointer to name in de - ld a, [wd0b5] - ld [wd11e], a - - ; TM names are separate from item names. - ; BUG: This applies to all names instead of just items. - cp HM_01 - jp nc, GetMachineName - - ld a, [H_LOADEDROMBANK] - push af - push hl - push bc - push de - ld a, [wNameListType] ;List3759_entrySelector - dec a - jr nz, .otherEntries - ;1 = MON_NAMES - call GetMonName - ld hl, NAME_LENGTH - add hl, de - ld e, l - ld d, h - jr .gotPtr -.otherEntries - ;2-7 = OTHER ENTRIES - ld a, [wPredefBank] - call BankswitchCommon - ld a, [wNameListType] ;VariousNames' entryID - dec a - add a - ld d, 0 - ld e, a - jr nc, .skip - inc d -.skip - ld hl, NamePointers - add hl, de - ld a, [hli] - ld [$ff96], a - ld a, [hl] - ld [$ff95], a - ld a, [$ff95] - ld h, a - ld a, [$ff96] - ld l, a - ld a, [wd0b5] - ld b, a - ld c, 0 -.nextName - ld d, h - ld e, l -.nextChar - ld a, [hli] - cp "@" - jr nz, .nextChar - inc c ;entry counter - ld a, b ;wanted entry - cp c - jr nz, .nextName - ld h, d - ld l, e - ld de, wcd6d - ld bc, $0014 - call CopyData -.gotPtr - ld a, e - ld [wUnusedCF8D], a - ld a, d - ld [wUnusedCF8D + 1], a - pop de - pop bc - pop hl - pop af - call BankswitchCommon - ret - -GetItemPrice:: -; Stores item's price as BCD at hItemPrice (3 bytes) -; Input: [wcf91] = item id - ld a, [H_LOADEDROMBANK] - push af - ld a, [wListMenuID] - cp MOVESLISTMENU - ld a, BANK(ItemPrices) - jr nz, .ok - ld a, $f ; hardcoded Bank -.ok - call BankswitchCommon - ld hl, wItemPrices - ld a, [hli] - ld h, [hl] - ld l, a - ld a, [wcf91] ; a contains item id - cp HM_01 - jr nc, .getTMPrice - ld bc, $3 -.loop - add hl, bc - dec a - jr nz, .loop - dec hl - ld a, [hld] - ld [hItemPrice + 2], a - ld a, [hld] - ld [hItemPrice + 1], a - ld a, [hl] - ld [hItemPrice], a - jr .done -.getTMPrice - callbs GetMachinePrice -.done - ld de, hItemPrice - pop af - call BankswitchCommon - ret - -; copies a string from [de] to [wcf4b] -CopyStringToCF4B:: - ld hl, wcf4b - ; fall through - -; copies a string from [de] to [hl] -CopyString:: - ld a, [de] - inc de - ld [hli], a - cp "@" - jr nz, CopyString - ret - -; this function is used when lower button sensitivity is wanted (e.g. menus) -; OUTPUT: [hJoy5] = pressed buttons in usual format -; there are two flags that control its functionality, [hJoy6] and [hJoy7] -; there are essentially three modes of operation -; 1. Get newly pressed buttons only -; ([hJoy7] == 0, [hJoy6] == any) -; Just copies [hJoyPressed] to [hJoy5]. -; 2. Get currently pressed buttons at low sample rate with delay -; ([hJoy7] == 1, [hJoy6] != 0) -; If the user holds down buttons for more than half a second, -; report buttons as being pressed up to 12 times per second thereafter. -; If the user holds down buttons for less than half a second, -; report only one button press. -; 3. Same as 2, but report no buttons as pressed if A or B is held down. -; ([hJoy7] == 1, [hJoy6] == 0) -JoypadLowSensitivity:: - call Joypad - ld a, [hJoy7] ; flag - and a ; get all currently pressed buttons or only newly pressed buttons? - ld a, [hJoyPressed] ; newly pressed buttons - jr z, .storeButtonState - ld a, [hJoyHeld] ; all currently pressed buttons -.storeButtonState - ld [hJoy5], a - ld a, [hJoyPressed] ; newly pressed buttons - and a ; have any buttons been newly pressed since last check? - jr z, .noNewlyPressedButtons -.newlyPressedButtons - ld a, 30 ; half a second delay - ld [H_FRAMECOUNTER], a - ret -.noNewlyPressedButtons - ld a, [H_FRAMECOUNTER] - and a ; is the delay over? - jr z, .delayOver -.delayNotOver - xor a - ld [hJoy5], a ; report no buttons as pressed - ret -.delayOver -; if [hJoy6] = 0 and A or B is pressed, report no buttons as pressed - ld a, [hJoyHeld] - and A_BUTTON | B_BUTTON - jr z, .setShortDelay - ld a, [hJoy6] ; flag - and a - jr nz, .setShortDelay - xor a - ld [hJoy5], a -.setShortDelay - ld a, 5 ; 1/12 of a second delay - ld [H_FRAMECOUNTER], a - ret - -WaitForTextScrollButtonPress:: - ld a, [H_DOWNARROWBLINKCNT1] - push af - ld a, [H_DOWNARROWBLINKCNT2] - push af - xor a - ld [H_DOWNARROWBLINKCNT1], a - ld a, $6 - ld [H_DOWNARROWBLINKCNT2], a -.loop - push hl - ld a, [wTownMapSpriteBlinkingEnabled] - and a - jr z, .skipAnimation - push de - push bc - callab TownMapSpriteBlinkingAnimation - pop bc - pop de -.skipAnimation - coord hl, 18, 16 - call HandleDownArrowBlinkTiming - pop hl - call JoypadLowSensitivity - predef CableClub_Run - ld a, [hJoy5] - and A_BUTTON | B_BUTTON - jr z, .loop - pop af - ld [H_DOWNARROWBLINKCNT2], a - pop af - ld [H_DOWNARROWBLINKCNT1], a - ret - -; (unless in link battle) waits for A or B being pressed and outputs the scrolling sound effect -ManualTextScroll:: - ld a, [wLinkState] - cp LINK_STATE_BATTLING - jr z, .inLinkBattle - call WaitForTextScrollButtonPress - call WaitForSoundToFinish - ld a, SFX_PRESS_AB - jp PlaySound -.inLinkBattle - ld c, 65 - jp DelayFrames - -; function to do multiplication -; all values are big endian -; INPUT -; FF96-FF98 = multiplicand -; FF99 = multiplier -; OUTPUT -; FF95-FF98 = product -Multiply:: - push hl - push bc - callab _Multiply - pop bc - pop hl - ret - -; function to do division -; all values are big endian -; INPUT -; FF95-FF98 = dividend -; FF99 = divisor -; b = number of bytes in the dividend (starting from FF95) -; OUTPUT -; FF95-FF98 = quotient -; FF99 = remainder -Divide:: - push hl - push de - push bc - homecall _Divide - pop bc - pop de - pop hl - ret - -; This function is used to wait a short period after printing a letter to the -; screen unless the player presses the A/B button or the delay is turned off -; through the [wd730] or [wLetterPrintingDelayFlags] flags. -PrintLetterDelay:: - ld a, [wd730] - bit 6, a - ret nz - ld a, [wLetterPrintingDelayFlags] - bit 1, a - ret z - push hl - push de - push bc - ld a, [wLetterPrintingDelayFlags] - bit 0, a - jr z, .waitOneFrame - ld a, [wOptions] - and $f - ld [H_FRAMECOUNTER], a - jr .checkButtons -.waitOneFrame - ld a, 1 - ld [H_FRAMECOUNTER], a -.checkButtons - call Joypad - ld a, [hJoyHeld] -.checkAButton - bit 0, a ; is the A button pressed? - jr z, .checkBButton - jr .endWait -.checkBButton - bit 1, a ; is the B button pressed? - jr z, .buttonsNotPressed -.endWait - call DelayFrame - jr .done -.buttonsNotPressed ; if neither A nor B is pressed - ld a, [H_FRAMECOUNTER] - and a - jr nz, .checkButtons -.done - pop bc - pop de - pop hl - ret - -; Copies [hl, bc) to [de, bc - hl). -; In other words, the source data is from hl up to but not including bc, -; and the destination is de. -CopyDataUntil:: - ld a, [hli] - ld [de], a - inc de - ld a, h - cp b - jr nz, CopyDataUntil - ld a, l - cp c - jr nz, CopyDataUntil - ret - -; Function to remove a pokemon from the party or the current box. -; wWhichPokemon determines the pokemon. -; [wRemoveMonFromBox] == 0 specifies the party. -; [wRemoveMonFromBox] != 0 specifies the current box. -RemovePokemon:: - jpab _RemovePokemon - -AddPartyMon:: - push hl - push de - push bc - callba _AddPartyMon - pop bc - pop de - pop hl - ret - -; calculates all 5 stats of current mon and writes them to [de] -CalcStats:: - ld c, $0 -.statsLoop - inc c - call CalcStat - ld a, [H_MULTIPLICAND + 1] - ld [de], a - inc de - ld a, [H_MULTIPLICAND + 2] - ld [de], a - inc de - ld a, c - cp NUM_STATS - jr nz, .statsLoop - ret - -; calculates stat c of current mon -; c: stat to calc (HP=1, Atk=2, Def=3, Spd=4, Spc=5) -; b: consider stat exp? -; hl: base ptr to stat exp values ([hl + 2*c - 1] and [hl + 2*c]) -CalcStat:: - push hl - push de - push bc - ld a, b - ld d, a - push hl - ld hl, wMonHeader - ld b, $0 - add hl, bc - ld a, [hl] ; read base value of stat - ld e, a - pop hl - push hl - sla c - ld a, d - and a - jr z, .statExpDone ; consider stat exp? - add hl, bc ; skip to corresponding stat exp value -.statExpLoop ; calculates ceil(Sqrt(stat exp)) in b - xor a - ld [H_MULTIPLICAND], a - ld [H_MULTIPLICAND + 1], a - inc b ; increment current stat exp bonus - ld a, b - cp $ff - jr z, .statExpDone - ld [H_MULTIPLICAND + 2], a - ld [H_MULTIPLIER], a - call Multiply - ld a, [hld] - ld d, a - ld a, [$ff98] - sub d - ld a, [hli] - ld d, a - ld a, [$ff97] - sbc d ; test if (current stat exp bonus)^2 < stat exp - jr c, .statExpLoop -.statExpDone - srl c - pop hl - push bc - ld bc, wPartyMon1DVs - (wPartyMon1HPExp - 1) ; also wEnemyMonDVs - wEnemyMonHP - add hl, bc - pop bc - ld a, c - cp $2 - jr z, .getAttackIV - cp $3 - jr z, .getDefenseIV - cp $4 - jr z, .getSpeedIV - cp $5 - jr z, .getSpecialIV -.getHpIV - push bc - ld a, [hl] ; Atk IV - swap a - and $1 - sla a - sla a - sla a - ld b, a - ld a, [hli] ; Def IV - and $1 - sla a - sla a - add b - ld b, a - ld a, [hl] ; Spd IV - swap a - and $1 - sla a - add b - ld b, a - ld a, [hl] ; Spc IV - and $1 - add b ; HP IV: LSB of the other 4 IVs - pop bc - jr .calcStatFromIV -.getAttackIV - ld a, [hl] - swap a - and $f - jr .calcStatFromIV -.getDefenseIV - ld a, [hl] - and $f - jr .calcStatFromIV -.getSpeedIV - inc hl - ld a, [hl] - swap a - and $f - jr .calcStatFromIV -.getSpecialIV - inc hl - ld a, [hl] - and $f -.calcStatFromIV - ld d, $0 - add e - ld e, a - jr nc, .noCarry - inc d ; de = Base + IV -.noCarry - sla e - rl d ; de = (Base + IV) * 2 - srl b - srl b ; b = ceil(Sqrt(stat exp)) / 4 - ld a, b - add e - jr nc, .noCarry2 - inc d ; de = (Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4 -.noCarry2 - ld [H_MULTIPLICAND + 2], a - ld a, d - ld [H_MULTIPLICAND + 1], a - xor a - ld [H_MULTIPLICAND], a - ld a, [wCurEnemyLVL] - ld [H_MULTIPLIER], a - call Multiply ; ((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level - ld a, [H_MULTIPLICAND] - ld [H_DIVIDEND], a - ld a, [H_MULTIPLICAND + 1] - ld [H_DIVIDEND + 1], a - ld a, [H_MULTIPLICAND + 2] - ld [H_DIVIDEND + 2], a - ld a, $64 - ld [H_DIVISOR], a - ld a, $3 - ld b, a - call Divide ; (((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level) / 100 - ld a, c - cp $1 - ld a, 5 ; + 5 for non-HP stat - jr nz, .notHPStat - ld a, [wCurEnemyLVL] - ld b, a - ld a, [H_MULTIPLICAND + 2] - add b - ld [H_MULTIPLICAND + 2], a - jr nc, .noCarry3 - ld a, [H_MULTIPLICAND + 1] - inc a - ld [H_MULTIPLICAND + 1], a ; HP: (((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level) / 100 + Level -.noCarry3 - ld a, 10 ; + 10 for HP stat -.notHPStat - ld b, a - ld a, [H_MULTIPLICAND + 2] - add b - ld [H_MULTIPLICAND + 2], a - jr nc, .noCarry4 - ld a, [H_MULTIPLICAND + 1] - inc a ; non-HP: (((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level) / 100 + 5 - ld [H_MULTIPLICAND + 1], a ; HP: (((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level) / 100 + Level + 10 -.noCarry4 - ld a, [H_MULTIPLICAND + 1] ; check for overflow (>999) - cp 999 / $100 + 1 - jr nc, .overflow - cp 999 / $100 - jr c, .noOverflow - ld a, [H_MULTIPLICAND + 2] - cp 999 % $100 + 1 - jr c, .noOverflow -.overflow - ld a, 999 / $100 ; overflow: cap at 999 - ld [H_MULTIPLICAND + 1], a - ld a, 999 % $100 - ld [H_MULTIPLICAND + 2], a -.noOverflow - pop bc - pop de - pop hl - ret - -AddEnemyMonToPlayerParty:: - homecall_sf _AddEnemyMonToPlayerParty - ret - -MoveMon:: - homecall_sf _MoveMon - ret - -; skips a text entries, each of size NAME_LENGTH (like trainer name, OT name, rival name, ...) -; hl: base pointer, will be incremented by NAME_LENGTH * a -SkipFixedLengthTextEntries:: - and a - ret z - ld bc, NAME_LENGTH -.skipLoop - add hl, bc - dec a - jr nz, .skipLoop - ret - -AddNTimes:: -; add bc to hl a times - and a - ret z -.loop - add hl, bc - dec a - jr nz, .loop - ret - -; Compare strings, c bytes in length, at de and hl. -; Often used to compare big endian numbers in battle calculations. -StringCmp:: - ld a, [de] - cp [hl] - ret nz - inc de - inc hl - dec c - jr nz, StringCmp - ret - -; INPUT: -; a = oam block index (each block is 4 oam entries) -; b = Y coordinate of upper left corner of sprite -; c = X coordinate of upper left corner of sprite -; de = base address of 4 tile number and attribute pairs -WriteOAMBlock:: - ld h, wOAMBuffer / $100 - swap a ; multiply by 16 - ld l, a - call .writeOneEntry ; upper left - push bc - ld a, 8 - add c - ld c, a - call .writeOneEntry ; upper right - pop bc - ld a, 8 - add b - ld b, a - call .writeOneEntry ; lower left - ld a, 8 - add c - ld c, a - ; lower right -.writeOneEntry - ld [hl], b ; Y coordinate - inc hl - ld [hl], c ; X coordinate - inc hl - ld a, [de] ; tile number - inc de - ld [hli], a - ld a, [de] ; attribute - inc de - ld [hli], a - ret - -HandleMenuInput:: - xor a - ld [wPartyMenuAnimMonEnabled], a - -HandleMenuInputPokemonSelection:: - ld a, [H_DOWNARROWBLINKCNT1] - push af - ld a, [H_DOWNARROWBLINKCNT2] - push af ; save existing values on stack - xor a - ld [H_DOWNARROWBLINKCNT1], a ; blinking down arrow timing value 1 - ld a, 6 - ld [H_DOWNARROWBLINKCNT2], a ; blinking down arrow timing value 2 -.loop1 - xor a - ld [wAnimCounter], a ; counter for pokemon shaking animation - call PlaceMenuCursor - call Delay3 -.loop2 - push hl - ld a, [wPartyMenuAnimMonEnabled] - and a ; is it a pokemon selection menu? - jr z, .getJoypadState - callba AnimatePartyMon ; shake mini sprite of selected pokemon -.getJoypadState - pop hl - call JoypadLowSensitivity - ld a, [hJoy5] - and a ; was a key pressed? - jr nz, .keyPressed - push hl - coord hl, 18, 11 ; coordinates of blinking down arrow in some menus - call HandleDownArrowBlinkTiming ; blink down arrow (if any) - pop hl - ld a, [wMenuJoypadPollCount] - dec a - jr z, .giveUpWaiting - jr .loop2 -.giveUpWaiting -; if a key wasn't pressed within the specified number of checks - pop af - ld [H_DOWNARROWBLINKCNT2], a - pop af - ld [H_DOWNARROWBLINKCNT1], a ; restore previous values - xor a - ld [wMenuWrappingEnabled], a ; disable menu wrapping - ret -.keyPressed - xor a - ld [wCheckFor180DegreeTurn], a - ld a, [hJoy5] - ld b, a - bit 0, a ; pressed A key? - jr nz, .checkOtherKeys - bit 6, a ; pressed Up key? - jr z, .checkIfDownPressed -.upPressed - ld a, [wCurrentMenuItem] ; selected menu item - and a ; already at the top of the menu? - jr z, .alreadyAtTop -.notAtTop - dec a - ld [wCurrentMenuItem], a ; move selected menu item up one space - jr .checkOtherKeys -.alreadyAtTop - ld a, [wMenuWrappingEnabled] - and a ; is wrapping around enabled? - jr z, .noWrappingAround - ld a, [wMaxMenuItem] - ld [wCurrentMenuItem], a ; wrap to the bottom of the menu - jr .checkOtherKeys -.checkIfDownPressed - bit 7, a - jr z, .checkOtherKeys -.downPressed - ld a, [wCurrentMenuItem] - inc a - ld c, a - ld a, [wMaxMenuItem] - cp c - jr nc, .notAtBottom -.alreadyAtBottom - ld a, [wMenuWrappingEnabled] - and a ; is wrapping around enabled? - jr z, .noWrappingAround - ld c, $00 ; wrap from bottom to top -.notAtBottom - ld a, c - ld [wCurrentMenuItem], a -.checkOtherKeys - ld a, [wMenuWatchedKeys] - and b ; does the menu care about any of the pressed keys? - jp z, .loop1 -.checkIfAButtonOrBButtonPressed - ld a, [hJoy5] - and A_BUTTON | B_BUTTON - jr z, .skipPlayingSound -.AButtonOrBButtonPressed - push hl - ld hl, wFlags_0xcd60 - bit 5, [hl] - pop hl - jr nz, .skipPlayingSound - ld a, SFX_PRESS_AB - call PlaySound -.skipPlayingSound - pop af - ld [H_DOWNARROWBLINKCNT2], a - pop af - ld [H_DOWNARROWBLINKCNT1], a ; restore previous values - xor a - ld [wMenuWrappingEnabled], a ; disable menu wrapping - ld a, [hJoy5] - ret -.noWrappingAround - ld a, [wMenuWatchMovingOutOfBounds] - and a ; should we return if the user tried to go past the top or bottom? - jr z, .checkOtherKeys - jr .checkIfAButtonOrBButtonPressed - -PlaceMenuCursor:: - ld a, [wTopMenuItemY] - and a ; is the y coordinate 0? - jr z, .adjustForXCoord - coord hl, 0, 0 - ld bc, SCREEN_WIDTH -.topMenuItemLoop - add hl, bc - dec a - jr nz, .topMenuItemLoop -.adjustForXCoord - ld a, [wTopMenuItemX] - ld b, 0 - ld c, a - add hl, bc - push hl - ld a, [wLastMenuItem] - and a ; was the previous menu id 0? - jr z, .checkForArrow1 - ld bc, 40 - push af - ld a, [hFlags_0xFFFA] - bit 1, a ; is the menu double spaced? - jr z, .doubleSpaced1 - ld bc, 20 -.doubleSpaced1 - pop af -.oldMenuItemLoop - add hl, bc - dec a - jr nz, .oldMenuItemLoop -.checkForArrow1 - ld a, [hl] - cp "▶" ; was an arrow next to the previously selected menu item? - jr nz, .skipClearingArrow -.clearArrow - ld a, [wTileBehindCursor] - ld [hl], a -.skipClearingArrow - pop hl - ld a, [wCurrentMenuItem] - and a - jr z, .checkForArrow2 - ld bc, 40 - push af - ld a, [hFlags_0xFFFA] - bit 1, a ; is the menu double spaced? - jr z, .doubleSpaced2 - ld bc, 20 -.doubleSpaced2 - pop af -.currentMenuItemLoop - add hl, bc - dec a - jr nz, .currentMenuItemLoop -.checkForArrow2 - ld a, [hl] - cp "▶" ; has the right arrow already been placed? - jr z, .skipSavingTile ; if so, don't lose the saved tile - ld [wTileBehindCursor], a ; save tile before overwriting with right arrow -.skipSavingTile - ld a, "▶" ; place right arrow - ld [hl], a - ld a, l - ld [wMenuCursorLocation], a - ld a, h - ld [wMenuCursorLocation + 1], a - ld a, [wCurrentMenuItem] - ld [wLastMenuItem], a - ret - -; This is used to mark a menu cursor other than the one currently being -; manipulated. In the case of submenus, this is used to show the location of -; the menu cursor in the parent menu. In the case of swapping items in list, -; this is used to mark the item that was first chosen to be swapped. -PlaceUnfilledArrowMenuCursor:: - ld b, a - ld a, [wMenuCursorLocation] - ld l, a - ld a, [wMenuCursorLocation + 1] - ld h, a - ld [hl], $ec ; outline of right arrow - ld a, b - ret - -; Replaces the menu cursor with a blank space. -EraseMenuCursor:: - ld a, [wMenuCursorLocation] - ld l, a - ld a, [wMenuCursorLocation + 1] - ld h, a - ld [hl], " " - ret - -; This toggles a blinking down arrow at hl on and off after a delay has passed. -; This is often called even when no blinking is occurring. -; The reason is that most functions that call this initialize H_DOWNARROWBLINKCNT1 to 0. -; The effect is that if the tile at hl is initialized with a down arrow, -; this function will toggle that down arrow on and off, but if the tile isn't -; initialized with a down arrow, this function does nothing. -; That allows this to be called without worrying about if a down arrow should -; be blinking. -HandleDownArrowBlinkTiming:: - ld a, [hl] - ld b, a - ld a, "▼" - cp b - jr nz, .downArrowOff -.downArrowOn - ld a, [H_DOWNARROWBLINKCNT1] - dec a - ld [H_DOWNARROWBLINKCNT1], a - ret nz - ld a, [H_DOWNARROWBLINKCNT2] - dec a - ld [H_DOWNARROWBLINKCNT2], a - ret nz - ld a, " " - ld [hl], a - ld a, $ff - ld [H_DOWNARROWBLINKCNT1], a - ld a, $06 - ld [H_DOWNARROWBLINKCNT2], a - ret -.downArrowOff - ld a, [H_DOWNARROWBLINKCNT1] - and a - ret z - dec a - ld [H_DOWNARROWBLINKCNT1], a - ret nz - dec a - ld [H_DOWNARROWBLINKCNT1], a - ld a, [H_DOWNARROWBLINKCNT2] - dec a - ld [H_DOWNARROWBLINKCNT2], a - ret nz - ld a, $06 - ld [H_DOWNARROWBLINKCNT2], a - ld a, "▼" - ld [hl], a - ret - -; The following code either enables or disables the automatic drawing of -; text boxes by DisplayTextID. Both functions cause DisplayTextID to wait -; for a button press after displaying text (unless [wEnteringCableClub] is set). - -EnableAutoTextBoxDrawing:: - xor a - jr AutoTextBoxDrawingCommon - -DisableAutoTextBoxDrawing:: - ld a, $01 - -AutoTextBoxDrawingCommon:: - ld [wAutoTextBoxDrawingControl], a - xor a - ld [wDoNotWaitForButtonPressAfterDisplayingText], a ; make DisplayTextID wait for button press - ret - -PrintText:: -; Print text hl at (1, 14). - push hl - ld a, MESSAGE_BOX - ld [wTextBoxID], a - call DisplayTextBoxID - call UpdateSprites - call Delay3 - pop hl -PrintText_NoCreatingTextBox:: - coord bc, 1, 14 - jp TextCommandProcessor +INCLUDE "home/npc_movement.asm" +INCLUDE "home/trainers.asm" +INCLUDE "home/map_objects.asm" +INCLUDE "home/trainers2.asm" +INCLUDE "home/money.asm" +INCLUDE "home/bankswitch.asm" +INCLUDE "home/yes_no.asm" +INCLUDE "home/pathfinding.asm" +INCLUDE "home/load_font.asm" +INCLUDE "home/tilemap.asm" +INCLUDE "home/delay.asm" +INCLUDE "home/names2.asm" +INCLUDE "home/item_price.asm" +INCLUDE "home/copy_string.asm" +INCLUDE "home/joypad2.asm" +INCLUDE "home/math.asm" +INCLUDE "home/print_text.asm" +INCLUDE "home/move_mon.asm" +INCLUDE "home/array.asm" +INCLUDE "home/compare.asm" +INCLUDE "home/oam.asm" +INCLUDE "home/window.asm" FarPrintText:: ; print text b:hl at (1, 14) - ld a, [H_LOADEDROMBANK] + ldh a, [hLoadedROMBank] push af ld a, b call BankswitchCommon @@ -4355,421 +229,34 @@ FarPrintText:: call BankswitchCommon ret -PrintNumber:: -; Print the c-digit, b-byte value at de. -; Allows 2 to 7 digits. For 1-digit numbers, add -; the value to char "0" instead of calling PrintNumber. -; Flags LEADING_ZEROES and LEFT_ALIGN can be given -; in bits 7 and 6 of b respectively. - push bc - xor a - ld [H_PASTLEADINGZEROES], a - ld [H_NUMTOPRINT], a - ld [H_NUMTOPRINT + 1], a - ld a, b - and $f - cp 1 - jr z, .byte - cp 2 - jr z, .word -.long - ld a, [de] - ld [H_NUMTOPRINT], a - inc de - ld a, [de] - ld [H_NUMTOPRINT + 1], a - inc de - ld a, [de] - ld [H_NUMTOPRINT + 2], a - jr .start - -.word - ld a, [de] - ld [H_NUMTOPRINT + 1], a - inc de - ld a, [de] - ld [H_NUMTOPRINT + 2], a - jr .start - -.byte - ld a, [de] - ld [H_NUMTOPRINT + 2], a - -.start - push de - - ld d, b - ld a, c - ld b, a - xor a - ld c, a - ld a, b - - cp 2 - jr z, .tens - cp 3 - jr z, .hundreds - cp 4 - jr z, .thousands - cp 5 - jr z, .ten_thousands - cp 6 - jr z, .hundred_thousands - -print_digit: macro - -if (\1) / $10000 - ld a, \1 / $10000 % $100 -else xor a -endc - ld [H_POWEROFTEN + 0], a - -if (\1) / $100 - ld a, \1 / $100 % $100 -else xor a -endc - ld [H_POWEROFTEN + 1], a - - ld a, \1 / $1 % $100 - ld [H_POWEROFTEN + 2], a - - call .PrintDigit - call .NextDigit -endm - -.millions print_digit 1000000 -.hundred_thousands print_digit 100000 -.ten_thousands print_digit 10000 -.thousands print_digit 1000 -.hundreds print_digit 100 - -.tens - ld c, 0 - ld a, [H_NUMTOPRINT + 2] -.mod - cp 10 - jr c, .ok - sub 10 - inc c - jr .mod -.ok - - ld b, a - ld a, [H_PASTLEADINGZEROES] - or c - ld [H_PASTLEADINGZEROES], a - jr nz, .past - call .PrintLeadingZero - jr .next -.past - ld a, "0" - add c - ld [hl], a -.next - - call .NextDigit -.ones - ld a, "0" - add b - ld [hli], a - pop de - dec de - pop bc - ret - -.PrintDigit: -; Divide by the current decimal place. -; Print the quotient, and keep the modulus. - ld c, 0 -.loop - ld a, [H_POWEROFTEN] - ld b, a - ld a, [H_NUMTOPRINT] - ld [H_SAVEDNUMTOPRINT], a - cp b - jr c, .underflow0 - sub b - ld [H_NUMTOPRINT], a - ld a, [H_POWEROFTEN + 1] - ld b, a - ld a, [H_NUMTOPRINT + 1] - ld [H_SAVEDNUMTOPRINT + 1], a - cp b - jr nc, .noborrow1 - - ld a, [H_NUMTOPRINT] - or 0 - jr z, .underflow1 - dec a - ld [H_NUMTOPRINT], a - ld a, [H_NUMTOPRINT + 1] -.noborrow1 - - sub b - ld [H_NUMTOPRINT + 1], a - ld a, [H_POWEROFTEN + 2] - ld b, a - ld a, [H_NUMTOPRINT + 2] - ld [H_SAVEDNUMTOPRINT + 2], a - cp b - jr nc, .noborrow2 - - ld a, [H_NUMTOPRINT + 1] - and a - jr nz, .borrowed - - ld a, [H_NUMTOPRINT] - and a - jr z, .underflow2 - dec a - ld [H_NUMTOPRINT], a - xor a -.borrowed - - dec a - ld [H_NUMTOPRINT + 1], a - ld a, [H_NUMTOPRINT + 2] -.noborrow2 - sub b - ld [H_NUMTOPRINT + 2], a - inc c - jr .loop - -.underflow2 - ld a, [H_SAVEDNUMTOPRINT + 1] - ld [H_NUMTOPRINT + 1], a -.underflow1 - ld a, [H_SAVEDNUMTOPRINT] - ld [H_NUMTOPRINT], a -.underflow0 - ld a, [H_PASTLEADINGZEROES] - or c - jr z, .PrintLeadingZero - - ld a, "0" - add c - ld [hl], a - ld [H_PASTLEADINGZEROES], a - ret - -.PrintLeadingZero: - bit BIT_LEADING_ZEROES, d - ret z - ld [hl], "0" - ret - -.NextDigit: -; Increment unless the number is left-aligned, -; leading zeroes are not printed, and no digits -; have been printed yet. - bit BIT_LEADING_ZEROES, d - jr nz, .inc - bit BIT_LEFT_ALIGN, d - jr z, .inc - ld a, [H_PASTLEADINGZEROES] - and a - ret z -.inc - inc hl - ret - - -CallFunctionInTable:: -; Call function a in jumptable hl. -; de is not preserved. - push hl - push de - push bc - add a - ld d, 0 - ld e, a - add hl, de - ld a, [hli] - ld h, [hl] - ld l, a - ld de, .returnAddress - push de - jp hl -.returnAddress - pop bc - pop de - pop hl - ret - - -IsInArray:: -; Search an array at hl for the value in a. -; Entry size is de bytes. -; Return count b and carry if found. - ld b, 0 - -IsInRestOfArray:: - ld c, a -.loop - ld a, [hl] - cp -1 - jr z, .notfound - cp c - jr z, .found - inc b - add hl, de - jr .loop - -.notfound - and a - ret - -.found - scf - ret +INCLUDE "home/print_num.asm" +INCLUDE "home/array2.asm" InitMapSprites:: - jpab _InitMapSprites - -RestoreScreenTilesAndReloadTilePatterns:: - call ClearSprites - ld a, $1 - ld [wUpdateSpritesEnabled], a - call ReloadMapSpriteTilePatterns - call LoadScreenTilesFromBuffer2 - call LoadTextBoxTilePatterns - call RunDefaultPaletteCommand - jr Delay3 - - -GBPalWhiteOutWithDelay3:: - call GBPalWhiteOut - -Delay3:: -; The bg map is updated each frame in thirds. -; Wait three frames to let the bg map fully update. - ld c, 3 - jp DelayFrames - -GBPalNormal:: -; Reset BGP and OBP0. - ld a, %11100100 ; 3210 - ld [rBGP], a - ld a, %11010000 ; 3100 - ld [rOBP0], a - call UpdateGBCPal_BGP - call UpdateGBCPal_OBP0 - call UpdateGBCPal_OBP1 - ret - -GBPalWhiteOut:: -; White out all palettes. - xor a - ld [rBGP], a - ld [rOBP0], a - ld [rOBP1], a - call UpdateGBCPal_BGP - call UpdateGBCPal_OBP0 - call UpdateGBCPal_OBP1 - ret - - -RunDefaultPaletteCommand:: - ld b, $ff -RunPaletteCommand:: - ld a, [wOnSGB] - and a - ret z - predef_jump _RunPaletteCommand - -GetHealthBarColor:: -; Return at hl the palette of -; an HP bar e pixels long. - ld a, e - cp 27 - ld d, 0 ; green - jr nc, .gotColor - cp 10 - inc d ; yellow - jr nc, .gotColor - inc d ; red -.gotColor - ld [hl], d - ret - -; Copy the current map's sprites' tile patterns to VRAM again after they have -; been overwritten by other tile patterns. -ReloadMapSpriteTilePatterns:: - ld hl, wFontLoaded - ld a, [hl] - push af - res 0, [hl] - push hl - xor a - ld [wSpriteSetID], a - call DisableLCD - call InitMapSprites - call EnableLCD - pop hl - pop af - ld [hl], a - call LoadPlayerSpriteGraphics - call LoadFontTilePatterns - jp UpdateSprites + jpfar _InitMapSprites - -GiveItem:: -; Give player quantity c of item b, -; and copy the item's name to wcf4b. -; Return carry on success. - ld a, b - ld [wd11e], a - ld [wcf91], a - ld a, c - ld [wItemQuantity], a - ld hl, wNumBagItems - call AddItemToInventory - ret nc - call GetItemName - call CopyStringToCF4B - scf - ret - -GivePokemon:: -; Give the player monster b at level c. - ld a, b - ld [wcf91], a - ld a, c - ld [wCurEnemyLVL], a - xor a ; PLAYER_PARTY_DATA - ld [wMonDataLocation], a - jpba _GivePokemon - -Random:: -; Return a random number in a. -; For battles, use BattleRandom. - push hl - push de - push bc - callba Random_ - ld a, [hRandomAdd] - pop bc - pop de - pop hl - ret +INCLUDE "home/palettes.asm" +INCLUDE "home/reload_sprites.asm" +INCLUDE "home/give.asm" +INCLUDE "home/random.asm" BankswitchCommon:: - ld [H_LOADEDROMBANK], a + 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 - ld a, [H_LOADEDROMBANK] + ldh a, [hLoadedROMBank] push af ld a, b - ld [H_LOADEDROMBANK], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a call JumpToAddress pop bc ld a, b - ld [H_LOADEDROMBANK], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a ret JumpToAddress:: @@ -4794,139 +281,5 @@ PrepareRTCDataAndDisableSRAM:: ret INCLUDE "home/predef.asm" - -UpdateCinnabarGymGateTileBlocks:: - callba UpdateCinnabarGymGateTileBlocks_ - ret ; again? - ;jp Bankswitch - -CheckForHiddenObjectOrBookshelfOrCardKeyDoor:: - ld a, [H_LOADEDROMBANK] - push af - ld a, [hJoyHeld] - bit 0, a ; A button - jr z, .nothingFound -; A button is pressed - callbs CheckForHiddenObject - ld a, [$ffee] - and a - jr nz, .hiddenObjectNotFound - xor a - ld [$ffeb], a - ld a, [wHiddenObjectFunctionRomBank] - call BankswitchCommon - call JumpToAddress - ld a, [$ffeb] - jr .done -.hiddenObjectNotFound - predef GetTileAndCoordsInFrontOfPlayer - callba PrintBookshelfText - ld a, [$ffdb] - and a - jr z, .done -.nothingFound - ld a, $ff -.done - ld [$ffeb], a - pop af - call BankswitchCommon - ret - -PrintPredefTextID:: - ld [hSpriteIndexOrTextID], a - ld hl, TextPredefs - call SetMapTextPointer - ld hl, wTextPredefFlag - set 0, [hl] - call DisplayTextID - -RestoreMapTextPointer:: - ld hl, wMapTextPtr - ld a, [$ffec] - ld [hli], a - ld a, [$ffec + 1] - ld [hl], a - ret - -SetMapTextPointer:: - ld a, [wMapTextPtr] - ld [$ffec], a - ld a, [wMapTextPtr + 1] - ld [$ffec + 1], a - ld a, l - ld [wMapTextPtr], a - ld a, h - ld [wMapTextPtr + 1], a - ret - -TextPredefs:: -const_value = 1 - - add_tx_pre CardKeySuccessText ; 01 - add_tx_pre CardKeyFailText ; 02 - add_tx_pre RedBedroomPCText ; 03 - add_tx_pre RedBedroomSNESText ; 04 - add_tx_pre PushStartText ; 05 - add_tx_pre SaveOptionText ; 06 - add_tx_pre StrengthsAndWeaknessesText ; 07 - add_tx_pre OakLabEmailText ; 08 - add_tx_pre AerodactylFossilText ; 09 - add_tx_pre Route15UpstairsBinocularsText ; 0A - add_tx_pre KabutopsFossilText ; 0B - add_tx_pre FanClubPicture1Text ; 0C - add_tx_pre FanClubPicture2Text ; 0D - add_tx_pre GymStatueText1 ; 0E - add_tx_pre GymStatueText2 ; 0F - add_tx_pre BookcaseText ; 10 - add_tx_pre ViridianCityPokecenterBenchGuyText ; 11 - add_tx_pre PewterCityPokecenterBenchGuyText ; 12 - add_tx_pre CeruleanCityPokecenterBenchGuyText ; 13 - add_tx_pre LavenderCityPokecenterBenchGuyText ; 14 - add_tx_pre VermilionCityPokecenterBenchGuyText ; 15 - add_tx_pre CeladonCityPokecenterBenchGuyText ; 16 - add_tx_pre CeladonCityHotelText ; 17 - add_tx_pre FuchsiaCityPokecenterBenchGuyText ; 18 - add_tx_pre CinnabarIslandPokecenterBenchGuyText ; 19 - add_tx_pre SaffronCityPokecenterBenchGuyText ; 1A - add_tx_pre MtMoonPokecenterBenchGuyText ; 1B - add_tx_pre RockTunnelPokecenterBenchGuyText ; 1C - add_tx_pre UnusedBenchGuyText1 ; 1D - add_tx_pre UnusedBenchGuyText2 ; 1E - add_tx_pre UnusedBenchGuyText3 ; 1F - add_tx_pre UnusedPredefText ; 20 - add_tx_pre PokemonCenterPCText ; 21 - add_tx_pre ViridianSchoolNotebook ; 22 - add_tx_pre ViridianSchoolBlackboard ; 23 - add_tx_pre JustAMomentText ; 24 - add_tx_pre OpenBillsPCText ; 25 - add_tx_pre FoundHiddenItemText ; 26 - add_tx_pre HiddenItemBagFullText ; 27 - add_tx_pre VermilionGymTrashText ; 28 - add_tx_pre IndigoPlateauHQText ; 29 - add_tx_pre GameCornerOutOfOrderText ; 2A - add_tx_pre GameCornerOutToLunchText ; 2B - add_tx_pre GameCornerSomeonesKeysText ; 2C - add_tx_pre FoundHiddenCoinsText ; 2D - add_tx_pre DroppedHiddenCoinsText ; 2E - add_tx_pre BillsHouseMonitorText ; 2F - add_tx_pre BillsHouseInitiatedText ; 30 - add_tx_pre BillsHousePokemonList ; 31 - add_tx_pre MagazinesText ; 32 - add_tx_pre CinnabarGymQuiz ; 33 - add_tx_pre GameCornerNoCoinsText ; 34 - add_tx_pre GameCornerCoinCaseText ; 35 - add_tx_pre LinkCableHelp ; 36 - add_tx_pre TMNotebook ; 37 - add_tx_pre FightingDojoText ; 38 - add_tx_pre EnemiesOnEverySideText ; 39 - add_tx_pre WhatGoesAroundComesAroundText ; 3A - add_tx_pre NewBicycleText ; 3B - add_tx_pre IndigoPlateauStatues ; 3C XXX unused - add_tx_pre VermilionGymTrashSuccessText1 ; 3D - add_tx_pre VermilionGymTrashSuccessText2 ; 3E - add_tx_pre VermilionGymTrashSuccessText3 ; 3F - add_tx_pre VermilionGymTrashFailText ; 40 - add_tx_pre TownMapText ; 41 - add_tx_pre BookOrSculptureText ; 42 - add_tx_pre ElevatorText ; 43 - add_tx_pre PokemonStuffText ; 44 +INCLUDE "home/hidden_objects.asm" +INCLUDE "home/predef_text.asm" |