diff options
Diffstat (limited to 'home')
58 files changed, 2342 insertions, 625 deletions
diff --git a/home/array.asm b/home/array.asm new file mode 100644 index 00000000..256c58e1 --- /dev/null +++ b/home/array.asm @@ -0,0 +1,21 @@ +; 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 diff --git a/home/array2.asm b/home/array2.asm new file mode 100644 index 00000000..f4ed8389 --- /dev/null +++ b/home/array2.asm @@ -0,0 +1,47 @@ +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 diff --git a/home/audio.asm b/home/audio.asm index 04f0276d..426506bf 100644 --- a/home/audio.asm +++ b/home/audio.asm @@ -170,10 +170,10 @@ PlaySound:: .noFadeOut xor a ld [wNewSoundID], a - ld a, [hLoadedROMBank] - ld [hSavedROMBank], a + ldh a, [hLoadedROMBank] + ldh [hSavedROMBank], a ld a, [wAudioROMBank] - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a cp BANK(Audio1_PlaySound) jr nz, .checkForAudio2 @@ -197,8 +197,8 @@ PlaySound:: call Audio3_PlaySound .next2 - ld a, [hSavedROMBank] - ld [hLoadedROMBank], a + ldh a, [hSavedROMBank] + ldh [hLoadedROMBank], a ld [MBC1RomBank], a jr .done diff --git a/home/bankswitch.asm b/home/bankswitch.asm index 086ca2f3..52c8a45c 100644 --- a/home/bankswitch.asm +++ b/home/bankswitch.asm @@ -2,27 +2,27 @@ BankswitchHome:: ; switches to bank # in a ; Only use this when in the home bank! ld [wBankswitchHomeTemp], a - ld a, [hLoadedROMBank] + ldh a, [hLoadedROMBank] ld [wBankswitchHomeSavedROMBank], a ld a, [wBankswitchHomeTemp] - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a ret BankswitchBack:: ; returns from BankswitchHome ld a, [wBankswitchHomeSavedROMBank] - ld [hLoadedROMBank], 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, [hLoadedROMBank] + ldh a, [hLoadedROMBank] push af ld a, b - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a ld bc, .Return push bc @@ -30,6 +30,6 @@ Bankswitch:: .Return pop bc ld a, b - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a ret diff --git a/home/compare.asm b/home/compare.asm new file mode 100644 index 00000000..e2da7857 --- /dev/null +++ b/home/compare.asm @@ -0,0 +1,11 @@ +; 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 diff --git a/home/copy.asm b/home/copy.asm index 910f508b..880d1fb7 100644 --- a/home/copy.asm +++ b/home/copy.asm @@ -1,14 +1,14 @@ FarCopyData:: ; Copy bc bytes from a:hl to de. ld [wBuffer], a - ld a, [hLoadedROMBank] + ldh a, [hLoadedROMBank] push af ld a, [wBuffer] - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a call CopyData pop af - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a ret diff --git a/home/copy2.asm b/home/copy2.asm index 521223b6..1c9a56f3 100644 --- a/home/copy2.asm +++ b/home/copy2.asm @@ -1,25 +1,25 @@ FarCopyData2:: ; Identical to FarCopyData, but uses hROMBankTemp ; as temp space instead of wBuffer. - ld [hROMBankTemp], a - ld a, [hLoadedROMBank] + ldh [hROMBankTemp], a + ldh a, [hLoadedROMBank] push af - ld a, [hROMBankTemp] - ld [hLoadedROMBank], a + ldh a, [hROMBankTemp] + ldh [hLoadedROMBank], a ld [MBC1RomBank], a call CopyData pop af - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a ret FarCopyData3:: ; Copy bc bytes from a:de to hl. - ld [hROMBankTemp], a - ld a, [hLoadedROMBank] + ldh [hROMBankTemp], a + ldh a, [hLoadedROMBank] push af - ld a, [hROMBankTemp] - ld [hLoadedROMBank], a + ldh a, [hROMBankTemp] + ldh [hLoadedROMBank], a ld [MBC1RomBank], a push hl push de @@ -31,18 +31,18 @@ FarCopyData3:: pop de pop hl pop af - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a ret FarCopyDataDouble:: ; Expand bc bytes of 1bpp image data ; from a:hl to 2bpp data at de. - ld [hROMBankTemp], a - ld a, [hLoadedROMBank] + ldh [hROMBankTemp], a + ldh a, [hLoadedROMBank] push af - ld a, [hROMBankTemp] - ld [hLoadedROMBank], a + ldh a, [hROMBankTemp] + ldh [hLoadedROMBank], a ld [MBC1RomBank], a .loop ld a, [hli] @@ -55,7 +55,7 @@ FarCopyDataDouble:: or b jr nz, .loop pop af - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a ret @@ -64,27 +64,27 @@ CopyVideoData:: ; tiles from b:de to hl, 8 tiles at a time. ; This takes c/8 frames. - ld a, [hAutoBGTransferEnabled] + ldh a, [hAutoBGTransferEnabled] push af xor a ; disable auto-transfer while copying - ld [hAutoBGTransferEnabled], a + ldh [hAutoBGTransferEnabled], a - ld a, [hLoadedROMBank] - ld [hROMBankTemp], a + ldh a, [hLoadedROMBank] + ldh [hROMBankTemp], a ld a, b - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a ld a, e - ld [hVBlankCopySource], a + ldh [hVBlankCopySource], a ld a, d - ld [hVBlankCopySource + 1], a + ldh [hVBlankCopySource + 1], a ld a, l - ld [hVBlankCopyDest], a + ldh [hVBlankCopyDest], a ld a, h - ld [hVBlankCopyDest + 1], a + ldh [hVBlankCopyDest + 1], a .loop ld a, c @@ -92,18 +92,18 @@ CopyVideoData:: jr nc, .keepgoing .done - ld [hVBlankCopySize], a + ldh [hVBlankCopySize], a call DelayFrame - ld a, [hROMBankTemp] - ld [hLoadedROMBank], a + ldh a, [hROMBankTemp] + ldh [hLoadedROMBank], a ld [MBC1RomBank], a pop af - ld [hAutoBGTransferEnabled], a + ldh [hAutoBGTransferEnabled], a ret .keepgoing ld a, 8 - ld [hVBlankCopySize], a + ldh [hVBlankCopySize], a call DelayFrame ld a, c sub 8 @@ -114,26 +114,26 @@ CopyVideoDataDouble:: ; Wait for the next VBlank, then copy c 1bpp ; tiles from b:de to hl, 8 tiles at a time. ; This takes c/8 frames. - ld a, [hAutoBGTransferEnabled] + ldh a, [hAutoBGTransferEnabled] push af xor a ; disable auto-transfer while copying - ld [hAutoBGTransferEnabled], a - ld a, [hLoadedROMBank] - ld [hROMBankTemp], a + ldh [hAutoBGTransferEnabled], a + ldh a, [hLoadedROMBank] + ldh [hROMBankTemp], a ld a, b - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a ld a, e - ld [hVBlankCopyDoubleSource], a + ldh [hVBlankCopyDoubleSource], a ld a, d - ld [hVBlankCopyDoubleSource + 1], a + ldh [hVBlankCopyDoubleSource + 1], a ld a, l - ld [hVBlankCopyDoubleDest], a + ldh [hVBlankCopyDoubleDest], a ld a, h - ld [hVBlankCopyDoubleDest + 1], a + ldh [hVBlankCopyDoubleDest + 1], a .loop ld a, c @@ -141,18 +141,18 @@ CopyVideoDataDouble:: jr nc, .keepgoing .done - ld [hVBlankCopyDoubleSize], a + ldh [hVBlankCopyDoubleSize], a call DelayFrame - ld a, [hROMBankTemp] - ld [hLoadedROMBank], a + ldh a, [hROMBankTemp] + ldh [hLoadedROMBank], a ld [MBC1RomBank], a pop af - ld [hAutoBGTransferEnabled], a + ldh [hAutoBGTransferEnabled], a ret .keepgoing ld a, 8 - ld [hVBlankCopyDoubleSize], a + ldh [hVBlankCopyDoubleSize], a call DelayFrame ld a, c sub 8 @@ -184,32 +184,32 @@ CopyScreenTileBufferToVRAM:: ld c, 6 ld hl, $600 * 0 - coord de, 0, 6 * 0 + decoord 0, 6 * 0 call .setup call DelayFrame ld hl, $600 * 1 - coord de, 0, 6 * 1 + decoord 0, 6 * 1 call .setup call DelayFrame ld hl, $600 * 2 - coord de, 0, 6 * 2 + decoord 0, 6 * 2 call .setup jp DelayFrame .setup ld a, d - ld [hVBlankCopyBGSource+1], a + ldh [hVBlankCopyBGSource+1], a call GetRowColAddressBgMap ld a, l - ld [hVBlankCopyBGDest], a + ldh [hVBlankCopyBGDest], a ld a, h - ld [hVBlankCopyBGDest+1], a + ldh [hVBlankCopyBGDest+1], a ld a, c - ld [hVBlankCopyBGNumRows], a + ldh [hVBlankCopyBGNumRows], a ld a, e - ld [hVBlankCopyBGSource], a + ldh [hVBlankCopyBGSource], a ret ClearScreen:: @@ -217,7 +217,7 @@ ClearScreen:: ; for the bg map to update. ld bc, 20 * 18 inc b - coord hl, 0, 0 + hlcoord 0, 0 ld a, " " .loop ld [hli], a diff --git a/home/copy_string.asm b/home/copy_string.asm new file mode 100644 index 00000000..7f86e501 --- /dev/null +++ b/home/copy_string.asm @@ -0,0 +1,13 @@ +; 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 diff --git a/home/count_set_bits.asm b/home/count_set_bits.asm new file mode 100644 index 00000000..73f7fa9c --- /dev/null +++ b/home/count_set_bits.asm @@ -0,0 +1,24 @@ +; 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 diff --git a/home/delay.asm b/home/delay.asm new file mode 100644 index 00000000..850b23e9 --- /dev/null +++ b/home/delay.asm @@ -0,0 +1,31 @@ +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] + jr nz, .waitLoop + pop hl + ret diff --git a/home/fade.asm b/home/fade.asm index 9482fcb0..32175e16 100644 --- a/home/fade.asm +++ b/home/fade.asm @@ -11,11 +11,11 @@ LoadGBPal:: dec h .ok ld a, [hli] - ld [rBGP], a + ldh [rBGP], a ld a, [hli] - ld [rOBP0], a + ldh [rOBP0], a ld a, [hli] - ld [rOBP1], a + ldh [rOBP1], a ret GBFadeInFromBlack:: @@ -29,11 +29,11 @@ GBFadeOutToWhite:: GBFadeIncCommon: ld a, [hli] - ld [rBGP], a + ldh [rBGP], a ld a, [hli] - ld [rOBP0], a + ldh [rOBP0], a ld a, [hli] - ld [rOBP1], a + ldh [rOBP1], a ld c, 8 call DelayFrames dec b @@ -51,11 +51,11 @@ GBFadeInFromWhite:: GBFadeDecCommon: ld a, [hld] - ld [rOBP1], a + ldh [rOBP1], a ld a, [hld] - ld [rOBP0], a + ldh [rOBP0], a ld a, [hld] - ld [rBGP], a + ldh [rBGP], a ld c, 8 call DelayFrames dec b diff --git a/home/fade_audio.asm b/home/fade_audio.asm new file mode 100644 index 00000000..4ad2607d --- /dev/null +++ b/home/fade_audio.asm @@ -0,0 +1,48 @@ +FadeOutAudio:: + ld a, [wAudioFadeOutControl] + and a ; currently fading out audio? + jr nz, .fadingOut + ld a, [wd72c] + bit 1, a + ret nz + ld a, $77 + ldh [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 + ldh 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 + ldh [rNR50], a + ret +.fadeOutComplete + ld a, [wAudioFadeOutControl] + ld b, a + xor a + ld [wAudioFadeOutControl], a + ld a, SFX_STOP_ALL_MUSIC + ld [wNewSoundID], a + call PlaySound + ld a, [wAudioSavedROMBank] + ld [wAudioROMBank], a + ld a, b + ld [wNewSoundID], a + jp PlaySound diff --git a/home/give.asm b/home/give.asm new file mode 100644 index 00000000..cbfd0310 --- /dev/null +++ b/home/give.asm @@ -0,0 +1,26 @@ +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 + farjp _GivePokemon diff --git a/home/hidden_objects.asm b/home/hidden_objects.asm new file mode 100644 index 00000000..eccf1c8f --- /dev/null +++ b/home/hidden_objects.asm @@ -0,0 +1,39 @@ +UpdateCinnabarGymGateTileBlocks:: + farjp UpdateCinnabarGymGateTileBlocks_ + +CheckForHiddenObjectOrBookshelfOrCardKeyDoor:: + ldh a, [hLoadedROMBank] + push af + ldh a, [hJoyHeld] + bit 0, a ; A button + jr z, .nothingFound +; A button is pressed + ld a, BANK(CheckForHiddenObject) + ld [MBC1RomBank], a + ldh [hLoadedROMBank], a + call CheckForHiddenObject + ldh a, [hDidntFindAnyHiddenObject] + and a + jr nz, .hiddenObjectNotFound + ld a, [wHiddenObjectFunctionRomBank] + ld [MBC1RomBank], a + ldh [hLoadedROMBank], a + ld de, .returnAddress + push de + jp hl +.returnAddress + xor a + jr .done +.hiddenObjectNotFound + farcall PrintBookshelfText + ldh a, [hFFDB] + and a + jr z, .done +.nothingFound + ld a, $ff +.done + ldh [hItemAlreadyFound], a + pop af + ld [MBC1RomBank], a + ldh [hLoadedROMBank], a + ret diff --git a/home/init.asm b/home/init.asm index 83238bad..e3f5fdd4 100644 --- a/home/init.asm +++ b/home/init.asm @@ -21,22 +21,22 @@ rLCDC_DEFAULT EQU %11100011 di xor a - ld [rIF], a - ld [rIE], a - ld [rSCX], a - ld [rSCY], a - ld [rSB], a - ld [rSC], a - ld [rWX], a - ld [rWY], a - ld [rTMA], a - ld [rTAC], a - ld [rBGP], a - ld [rOBP0], a - ld [rOBP1], a + ldh [rIF], a + ldh [rIE], a + ldh [rSCX], a + ldh [rSCY], a + ldh [rSB], a + ldh [rSC], a + ldh [rWX], a + ldh [rWY], a + ldh [rTMA], a + ldh [rTAC], a + ldh [rBGP], a + ldh [rOBP0], a + ldh [rOBP1], a ld a, rLCDC_ENABLE_MASK - ld [rLCDC], a + ldh [rLCDC], a call DisableLCD ld sp, wStack @@ -60,37 +60,37 @@ rLCDC_DEFAULT EQU %11100011 call ClearSprites ld a, BANK(WriteDMACodeToHRAM) - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a call WriteDMACodeToHRAM xor a - ld [hTilesetType], a - ld [rSTAT], a - ld [hSCX], a - ld [hSCY], a - ld [rIF], a + ldh [hTilesetType], a + ldh [rSTAT], a + ldh [hSCX], a + ldh [hSCY], a + ldh [rIF], a ld a, 1 << VBLANK + 1 << TIMER + 1 << SERIAL - ld [rIE], a + ldh [rIE], a ld a, 144 ; move the window off-screen - ld [hWY], a - ld [rWY], a + ldh [hWY], a + ldh [rWY], a ld a, 7 - ld [rWX], a + ldh [rWX], a ld a, CONNECTION_NOT_ESTABLISHED - ld [hSerialConnectionStatus], a + ldh [hSerialConnectionStatus], a - ld h, vBGMap0 / $100 + ld h, HIGH(vBGMap0) call ClearBgMap - ld h, vBGMap1 / $100 + ld h, HIGH(vBGMap1) call ClearBgMap ld a, rLCDC_DEFAULT - ld [rLCDC], a + ldh [rLCDC], a ld a, 16 - ld [hSoftReset], a + ldh [hSoftReset], a call StopAllSounds ei @@ -101,9 +101,9 @@ rLCDC_DEFAULT EQU %11100011 ld [wAudioROMBank], a ld [wAudioSavedROMBank], a ld a, $9c - ld [hAutoBGTransferDest + 1], a + ldh [hAutoBGTransferDest + 1], a xor a - ld [hAutoBGTransferDest], a + ldh [hAutoBGTransferDest], a dec a ld [wUpdateSpritesEnabled], a @@ -114,7 +114,7 @@ rLCDC_DEFAULT EQU %11100011 call GBPalNormal call ClearSprites ld a, rLCDC_DEFAULT - ld [rLCDC], a + ldh [rLCDC], a jp SetDefaultNamesBeforeTitlescreen diff --git a/home/inventory.asm b/home/inventory.asm new file mode 100644 index 00000000..ebaa4047 --- /dev/null +++ b/home/inventory.asm @@ -0,0 +1,55 @@ +; subtracts the amount the player paid from their money +; OUTPUT: carry = 0(success) or 1(fail because there is not enough money) +SubtractAmountPaidFromMoney:: + farjp 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:: + ldh a, [hLoadedROMBank] + push af + ld a, BANK(RemoveItemFromInventory_) + ldh [hLoadedROMBank], a + ld [MBC1RomBank], a + call RemoveItemFromInventory_ + pop af + ldh [hLoadedROMBank], a + ld [MBC1RomBank], a + 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 + ldh a, [hLoadedROMBank] + push af + ld a, BANK(AddItemToInventory_) + ldh [hLoadedROMBank], a + ld [MBC1RomBank], a + call AddItemToInventory_ + pop bc + ld a, b + ldh [hLoadedROMBank], a + ld [MBC1RomBank], a + pop bc + ret diff --git a/home/item.asm b/home/item.asm new file mode 100644 index 00000000..f27d46f4 --- /dev/null +++ b/home/item.asm @@ -0,0 +1,49 @@ +; 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:: + farjp 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:: + ldh a, [hLoadedROMBank] + push af + ld a, BANK(TossItem_) + ldh [hLoadedROMBank], a + ld [MBC1RomBank], a + call TossItem_ + pop de + ld a, d + ldh [hLoadedROMBank], 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 + farcall IsKeyItem_ + pop bc + pop de + pop hl + ret diff --git a/home/item_price.asm b/home/item_price.asm new file mode 100644 index 00000000..98eb31b1 --- /dev/null +++ b/home/item_price.asm @@ -0,0 +1,44 @@ +GetItemPrice:: +; Stores item's price as BCD at hItemPrice (3 bytes) +; Input: [wcf91] = item id + ldh a, [hLoadedROMBank] + push af + ld a, [wListMenuID] + cp MOVESLISTMENU + ld a, BANK(ItemPrices) + jr nz, .ok + ld a, $f ; hardcoded Bank +.ok + ldh [hLoadedROMBank], a + ld [MBC1RomBank], a + ld hl, wItemPrices + ld a, [hli] + ld h, [hl] + ld l, a + ld a, [wcf91] ; a contains item id + cp HM01 + jr nc, .getTMPrice + ld bc, $3 +.loop + add hl, bc + dec a + jr nz, .loop + dec hl + ld a, [hld] + ldh [hItemPrice + 2], a + ld a, [hld] + ldh [hItemPrice + 1], a + ld a, [hl] + ldh [hItemPrice], a + jr .done +.getTMPrice + ld a, BANK(GetMachinePrice) + ldh [hLoadedROMBank], a + ld [MBC1RomBank], a + call GetMachinePrice +.done + ld de, hItemPrice + pop af + ldh [hLoadedROMBank], a + ld [MBC1RomBank], a + ret diff --git a/home/joypad.asm b/home/joypad.asm index 9948b6e7..51a77fcc 100644 --- a/home/joypad.asm +++ b/home/joypad.asm @@ -6,9 +6,9 @@ ReadJoypad:: ld a, 1 << 5 ; select direction keys ld c, 0 - ld [rJOYP], a + ldh [rJOYP], a REPT 6 - ld a, [rJOYP] + ldh a, [rJOYP] ENDR cpl and %1111 @@ -16,18 +16,18 @@ ReadJoypad:: ld b, a ld a, 1 << 4 ; select button keys - ld [rJOYP], a + ldh [rJOYP], a REPT 10 - ld a, [rJOYP] + ldh a, [rJOYP] ENDR cpl and %1111 or b - ld [hJoyInput], a + ldh [hJoyInput], a ld a, 1 << 4 + 1 << 5 ; deselect keys - ld [rJOYP], a + ldh [rJOYP], a ret Joypad:: diff --git a/home/joypad2.asm b/home/joypad2.asm new file mode 100644 index 00000000..139dd3f5 --- /dev/null +++ b/home/joypad2.asm @@ -0,0 +1,95 @@ +; 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 + ldh a, [hJoy7] ; flag + and a ; get all currently pressed buttons or only newly pressed buttons? + ldh a, [hJoyPressed] ; newly pressed buttons + jr z, .storeButtonState + ldh a, [hJoyHeld] ; all currently pressed buttons +.storeButtonState + ldh [hJoy5], a + ldh 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 + ldh [hFrameCounter], a + ret +.noNewlyPressedButtons + ldh a, [hFrameCounter] + and a ; is the delay over? + jr z, .delayOver +.delayNotOver + xor a + ldh [hJoy5], a ; report no buttons as pressed + ret +.delayOver +; if [hJoy6] = 0 and A or B is pressed, report no buttons as pressed + ldh a, [hJoyHeld] + and A_BUTTON | B_BUTTON + jr z, .setShortDelay + ldh a, [hJoy6] ; flag + and a + jr nz, .setShortDelay + xor a + ldh [hJoy5], a +.setShortDelay + ld a, 5 ; 1/12 of a second delay + ldh [hFrameCounter], a + ret + +WaitForTextScrollButtonPress:: + ldh a, [hDownArrowBlinkCount1] + push af + ldh a, [hDownArrowBlinkCount2] + push af + xor a + ldh [hDownArrowBlinkCount1], a + ld a, $6 + ldh [hDownArrowBlinkCount2], a +.loop + push hl + ld a, [wTownMapSpriteBlinkingEnabled] + and a + jr z, .skipAnimation + call TownMapSpriteBlinkingAnimation +.skipAnimation + hlcoord 18, 16 + call HandleDownArrowBlinkTiming + pop hl + call JoypadLowSensitivity + predef CableClub_Run + ldh a, [hJoy5] + and A_BUTTON | B_BUTTON + jr z, .loop + pop af + ldh [hDownArrowBlinkCount2], a + pop af + ldh [hDownArrowBlinkCount1], 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 + ld a, SFX_PRESS_AB + jp PlaySound +.inLinkBattle + ld c, 65 + jp DelayFrames diff --git a/home/lcd.asm b/home/lcd.asm index e88a42b3..72fc70ed 100644 --- a/home/lcd.asm +++ b/home/lcd.asm @@ -1,25 +1,25 @@ DisableLCD:: xor a - ld [rIF], a - ld a, [rIE] + ldh [rIF], a + ldh a, [rIE] ld b, a res 0, a - ld [rIE], a + ldh [rIE], a .wait - ld a, [rLY] + ldh a, [rLY] cp LY_VBLANK jr nz, .wait - ld a, [rLCDC] + ldh a, [rLCDC] and $ff ^ rLCDC_ENABLE_MASK - ld [rLCDC], a + ldh [rLCDC], a ld a, b - ld [rIE], a + ldh [rIE], a ret EnableLCD:: - ld a, [rLCDC] + ldh a, [rLCDC] set rLCDC_ENABLE, a - ld [rLCDC], a + ldh [rLCDC], a ret diff --git a/home/list_menu.asm b/home/list_menu.asm index 4ce973b2..ec775331 100644 --- a/home/list_menu.asm +++ b/home/list_menu.asm @@ -3,9 +3,9 @@ ; [wListPointer] = address of the list (2 bytes) DisplayListMenuID:: xor a - ld [hAutoBGTransferEnabled], a ; disable auto-transfer + ldh [hAutoBGTransferEnabled], a ; disable auto-transfer ld a, 1 - ld [hJoy7], a ; joypad state update flag + ldh [hJoy7], a ; joypad state update flag ld a, [wBattleType] and a ; is it the Old Man battle? jr nz, .specialBattleType @@ -31,7 +31,7 @@ DisplayListMenuID:: 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 + hlcoord 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? @@ -57,22 +57,22 @@ DisplayListMenuID:: DisplayListMenuIDLoop:: xor a - ld [hAutoBGTransferEnabled], a ; disable transfer + ldh [hAutoBGTransferEnabled], a ; disable transfer call PrintListMenuEntries ld a, 1 - ld [hAutoBGTransferEnabled], a ; enable transfer + ldh [hAutoBGTransferEnabled], 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 + ldcoord_a 5, 4 ; place menu cursor in front of first menu entry ld c, 80 call DelayFrames xor a ld [wCurrentMenuItem], a - coord hl, 5, 4 + hlcoord 5, 4 ld a, l ld [wMenuCursorLocation], a ld a, h @@ -163,7 +163,7 @@ DisplayListMenuIDLoop:: ld a, [wCurrentMenuItem] ld [wChosenMenuItem], a xor a - ld [hJoy7], a ; joypad state update flag + ldh [hJoy7], a ; joypad state update flag ld hl, wd730 res 6, [hl] ; turn on letter printing delay jp BankswitchBack @@ -194,23 +194,23 @@ DisplayListMenuIDLoop:: DisplayChooseQuantityMenu:: ; text box dimensions/coordinates for just quantity - coord hl, 15, 9 + hlcoord 15, 9 ld b, 1 ; height ld c, 3 ; width ld a, [wListMenuID] cp PRICEDITEMLISTMENU jr nz, .drawTextBox ; text box dimensions/coordinates for quantity and price - coord hl, 7, 9 + hlcoord 7, 9 ld b, 1 ; height ld c, 11 ; width .drawTextBox call TextBoxBorder - coord hl, 16, 10 + hlcoord 16, 10 ld a, [wListMenuID] cp PRICEDITEMLISTMENU jr nz, .printInitialQuantity - coord hl, 8, 10 + hlcoord 8, 10 .printInitialQuantity ld de, InitialQuantityText call PlaceString @@ -219,7 +219,7 @@ DisplayChooseQuantityMenu:: jp .incrementQuantity .waitForKeyPressLoop call JoypadLowSensitivity - ld a, [hJoyPressed] ; newly pressed buttons + ldh a, [hJoyPressed] ; newly pressed buttons bit 0, a ; was the A button pressed? jp nz, .buttonAPressed bit 1, a ; was the B button pressed? @@ -250,7 +250,7 @@ DisplayChooseQuantityMenu:: ld a, [wMaxItemQuantity] ld [hl], a .handleNewQuantity - coord hl, 17, 10 + hlcoord 17, 10 ld a, [wListMenuID] cp PRICEDITEMLISTMENU jr nz, .printQuantity @@ -272,30 +272,30 @@ DisplayChooseQuantityMenu:: pop bc dec b jr nz, .addLoop - ld a, [hHalveItemPrices] + ldh a, [hHalveItemPrices] and a ; should the price be halved (for selling items)? jr z, .skipHalvingPrice xor a - ld [hDivideBCDDivisor], a - ld [hDivideBCDDivisor + 1], a + ldh [hDivideBCDDivisor], a + ldh [hDivideBCDDivisor + 1], a ld a, $02 - ld [hDivideBCDDivisor + 2], a + ldh [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 + ldh a, [hDivideBCDQuotient] + ldh [hMoney], a + ldh a, [hDivideBCDQuotient + 1] + ldh [hMoney + 1], a + ldh a, [hDivideBCDQuotient + 2] + ldh [hMoney + 2], a .skipHalvingPrice - coord hl, 12, 10 + hlcoord 12, 10 ld de, SpacesBetweenQuantityAndPriceText call PlaceString ld de, hMoney ; total price ld c, $a3 call PrintBCDNumber - coord hl, 9, 10 + hlcoord 9, 10 .printQuantity ld de, wItemQuantity ; current quantity lb bc, LEADING_ZEROES | 1, 2 ; 1 byte, 2 digits @@ -324,7 +324,7 @@ ExitListMenu:: ld [wMenuExitMethod], a ld [wMenuWatchMovingOutOfBounds], a xor a - ld [hJoy7], a + ldh [hJoy7], a ld hl, wd730 res 6, [hl] call BankswitchBack @@ -334,7 +334,7 @@ ExitListMenu:: ret PrintListMenuEntries:: - coord hl, 5, 3 + hlcoord 5, 3 ld b, 9 ld c, 14 call ClearScreenArea @@ -359,7 +359,7 @@ PrintListMenuEntries:: jr nc, .noCarry inc d .noCarry - coord hl, 6, 4 ; coordinates of first list entry name + hlcoord 6, 4 ; coordinates of first list entry name ld b, 4 ; print 4 names .loop ld a, b diff --git a/home/load_font.asm b/home/load_font.asm new file mode 100644 index 00000000..3b56d3a8 --- /dev/null +++ b/home/load_font.asm @@ -0,0 +1,47 @@ +LoadFontTilePatterns:: + ldh 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:: + ldh a, [rLCDC] + bit 7, a ; is the LCD enabled? + jr nz, .on +.off + ld hl, TextBoxGraphics + ld de, vChars2 tile $60 + ld bc, TextBoxGraphicsEnd - TextBoxGraphics + ld a, BANK(TextBoxGraphics) + jp FarCopyData2 ; if LCD is off, transfer all at once +.on + ld de, TextBoxGraphics + ld hl, vChars2 tile $60 + lb bc, BANK(TextBoxGraphics), (TextBoxGraphicsEnd - TextBoxGraphics) / $10 + jp CopyVideoData ; if LCD is on, transfer during V-blank + +LoadHpBarAndStatusTilePatterns:: + ldh a, [rLCDC] + bit 7, a ; is the LCD enabled? + jr nz, .on +.off + ld hl, HpBarAndStatusGraphics + ld de, vChars2 tile $62 + ld bc, HpBarAndStatusGraphicsEnd - HpBarAndStatusGraphics + ld a, BANK(HpBarAndStatusGraphics) + jp FarCopyData2 ; if LCD is off, transfer all at once +.on + ld de, HpBarAndStatusGraphics + ld hl, vChars2 tile $62 + lb bc, BANK(HpBarAndStatusGraphics), (HpBarAndStatusGraphicsEnd - HpBarAndStatusGraphics) / $10 + jp CopyVideoData ; if LCD is on, transfer during V-blank diff --git a/home/map_objects.asm b/home/map_objects.asm new file mode 100644 index 00000000..02555e35 --- /dev/null +++ b/home/map_objects.asm @@ -0,0 +1,248 @@ +; 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 + +TextScript_ItemStoragePC:: + call SaveScreenTilesToBuffer2 + ld b, BANK(PlayerPC) + ld hl, PlayerPC + jr bankswitchAndContinue + +TextScript_BillsPC:: + call SaveScreenTilesToBuffer2 + ld b, BANK(BillsPC_) + ld hl, BillsPC_ + jr bankswitchAndContinue + +TextScript_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 + +TextScript_PokemonCenterPC:: + ld b, BANK(ActivatePC) + ld hl, ActivatePC + jr bankswitchAndContinue + +StartSimulatingJoypadStates:: + xor a + ld [wOverrideSimulatedJoypadStatesMask], a + ld [wSpritePlayerStateData2MovementByte1], a + 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 + +DisplayPokedex:: + ld [wd11e], a + farjp _DisplayPokedex + +SetSpriteFacingDirectionAndDelay:: + call SetSpriteFacingDirection + ld c, 6 + jp DelayFrames + +SetSpriteFacingDirection:: + ld a, $9 + ldh [hSpriteDataOffset], a + call GetPointerWithinSpriteStateData1 + ldh a, [hSpriteFacingDirection] + ld [hl], a + ret + +SetSpriteImageIndexAfterSettingFacingDirection:: + ld de, -7 + add hl, de + ld [hl], a + 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 +; [hSpriteIndex] = 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, wSpritePlayerStateData2MapY + ldh a, [hSpriteIndex] + 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: + ldh a, [hSpriteDataOffset] + ld b, a + ldh a, [hSpriteIndex] + 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 + ldh [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 + ldh 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 [hSpriteIndex] to $FE and byte 2 to [hSpriteMovementByte2] +SetSpriteMovementBytesToFE:: + push hl + call GetSpriteMovementByte1Pointer + ld [hl], $fe + call GetSpriteMovementByte2Pointer + ldh a, [hSpriteMovementByte2] + ld [hl], a + pop hl + ret + +; sets both movement bytes for sprite [hSpriteIndex] 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 [hSpriteIndex] in hl +GetSpriteMovementByte1Pointer:: + ld h, $C2 + ldh a, [hSpriteIndex] + swap a + add 6 + ld l, a + ret + +; returns the sprite movement byte 2 pointer for sprite [hSpriteIndex] in hl +GetSpriteMovementByte2Pointer:: + push de + ld hl, wMapSpriteData + ldh a, [hSpriteIndex] + dec a + add a + ld d, 0 + ld e, a + add hl, de + pop de + ret diff --git a/home/math.asm b/home/math.asm new file mode 100644 index 00000000..b081b540 --- /dev/null +++ b/home/math.asm @@ -0,0 +1,41 @@ +; function to do multiplication +; all values are big endian +; INPUT +; FF96-FF98 = multiplicand +; FF99 = multiplier +; OUTPUT +; FF95-FF98 = product +Multiply:: + push hl + push bc + callfar _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 + ldh a, [hLoadedROMBank] + push af + ld a, BANK(_Divide) + ldh [hLoadedROMBank], a + ld [MBC1RomBank], a + call _Divide + pop af + ldh [hLoadedROMBank], a + ld [MBC1RomBank], a + pop bc + pop de + pop hl + ret diff --git a/home/money.asm b/home/money.asm new file mode 100644 index 00000000..a62835ea --- /dev/null +++ b/home/money.asm @@ -0,0 +1,15 @@ +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 diff --git a/home/move_mon.asm b/home/move_mon.asm index e13ebf4e..3e69e6d0 100644 --- a/home/move_mon.asm +++ b/home/move_mon.asm @@ -1,15 +1,30 @@ +; Copies [hl, bc) to [de, 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 + jpfar _RemovePokemon AddPartyMon:: push hl push de push bc - callba _AddPartyMon + farcall _AddPartyMon pop bc pop de pop hl @@ -21,10 +36,10 @@ CalcStats:: .statsLoop inc c call CalcStat - ld a, [hMultiplicand+1] + ldh a, [hMultiplicand+1] ld [de], a inc de - ld a, [hMultiplicand+2] + ldh a, [hMultiplicand+2] ld [de], a inc de ld a, c @@ -57,22 +72,22 @@ CalcStat:: add hl, bc ; skip to corresponding stat exp value .statExpLoop ; calculates ceil(Sqrt(stat exp)) in b xor a - ld [hMultiplicand], a - ld [hMultiplicand+1], a + ldh [hMultiplicand], a + ldh [hMultiplicand+1], a inc b ; increment current stat exp bonus ld a, b cp $ff jr z, .statExpDone - ld [hMultiplicand+2], a - ld [hMultiplier], a + ldh [hMultiplicand+2], a + ldh [hMultiplier], a call Multiply ld a, [hld] ld d, a - ld a, [hProduct + 3] + ldh a, [hProduct + 3] sub d ld a, [hli] ld d, a - ld a, [hProduct + 2] + ldh a, [hProduct + 2] sbc d ; test if (current stat exp bonus)^2 < stat exp jr c, .statExpLoop .statExpDone @@ -152,22 +167,22 @@ CalcStat:: jr nc, .noCarry2 inc d ; de = (Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4 .noCarry2 - ld [hMultiplicand+2], a + ldh [hMultiplicand+2], a ld a, d - ld [hMultiplicand+1], a + ldh [hMultiplicand+1], a xor a - ld [hMultiplicand], a + ldh [hMultiplicand], a ld a, [wCurEnemyLVL] - ld [hMultiplier], a + ldh [hMultiplier], a call Multiply ; ((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level - ld a, [hMultiplicand] - ld [hDividend], a - ld a, [hMultiplicand+1] - ld [hDividend+1], a - ld a, [hMultiplicand+2] - ld [hDividend+2], a + ldh a, [hMultiplicand] + ldh [hDividend], a + ldh a, [hMultiplicand+1] + ldh [hDividend+1], a + ldh a, [hMultiplicand+2] + ldh [hDividend+2], a ld a, $64 - ld [hDivisor], a + ldh [hDivisor], a ld a, $3 ld b, a call Divide ; (((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level) / 100 @@ -177,38 +192,38 @@ CalcStat:: jr nz, .notHPStat ld a, [wCurEnemyLVL] ld b, a - ld a, [hMultiplicand+2] + ldh a, [hMultiplicand+2] add b - ld [hMultiplicand+2], a + ldh [hMultiplicand+2], a jr nc, .noCarry3 - ld a, [hMultiplicand+1] + ldh a, [hMultiplicand+1] inc a - ld [hMultiplicand+1], a ; HP: (((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level) / 100 + Level + ldh [hMultiplicand+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, [hMultiplicand+2] + ldh a, [hMultiplicand+2] add b - ld [hMultiplicand+2], a + ldh [hMultiplicand+2], a jr nc, .noCarry4 - ld a, [hMultiplicand+1] + ldh a, [hMultiplicand+1] inc a ; non-HP: (((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level) / 100 + 5 - ld [hMultiplicand+1], a ; HP: (((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level) / 100 + Level + 10 + ldh [hMultiplicand+1], a ; HP: (((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level) / 100 + Level + 10 .noCarry4 - ld a, [hMultiplicand+1] ; check for overflow (>999) - cp 999 / $100 + 1 + ldh a, [hMultiplicand+1] ; check for overflow (>999) + cp HIGH(MAX_STAT_VALUE) + 1 jr nc, .overflow - cp 999 / $100 + cp HIGH(MAX_STAT_VALUE) jr c, .noOverflow - ld a, [hMultiplicand+2] - cp 999 % $100 + 1 + ldh a, [hMultiplicand+2] + cp LOW(MAX_STAT_VALUE) + 1 jr c, .noOverflow .overflow - ld a, 999 / $100 ; overflow: cap at 999 - ld [hMultiplicand+1], a - ld a, 999 % $100 - ld [hMultiplicand+2], a + ld a, HIGH(MAX_STAT_VALUE) ; overflow: cap at 999 + ldh [hMultiplicand+1], a + ld a, LOW(MAX_STAT_VALUE) + ldh [hMultiplicand+2], a .noOverflow pop bc pop de @@ -216,27 +231,27 @@ CalcStat:: ret AddEnemyMonToPlayerParty:: - ld a, [hLoadedROMBank] + ldh a, [hLoadedROMBank] push af ld a, BANK(_AddEnemyMonToPlayerParty) - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a call _AddEnemyMonToPlayerParty pop bc ld a, b - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a ret MoveMon:: - ld a, [hLoadedROMBank] + ldh a, [hLoadedROMBank] push af ld a, BANK(_MoveMon) - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a call _MoveMon pop bc ld a, b - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a ret diff --git a/home/names.asm b/home/names.asm index 489bd040..f7751fa0 100644 --- a/home/names.asm +++ b/home/names.asm @@ -1,9 +1,9 @@ GetMonName:: push hl - ld a, [hLoadedROMBank] + ldh a, [hLoadedROMBank] push af ld a, BANK(MonsterNames) - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a ld a, [wd11e] dec a @@ -19,7 +19,7 @@ GetMonName:: ld [hl], "@" pop de pop af - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a pop hl ret diff --git a/home/names2.asm b/home/names2.asm index ecf6ae63..8f539c31 100644 --- a/home/names2.asm +++ b/home/names2.asm @@ -22,7 +22,7 @@ GetName:: cp HM01 jp nc, GetMachineName - ld a, [hLoadedROMBank] + ldh a, [hLoadedROMBank] push af push hl push bc @@ -40,7 +40,7 @@ GetName:: .otherEntries ;2-7 = OTHER ENTRIES ld a, [wPredefBank] - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a ld a, [wNameListType] ;VariousNames' entryID dec a @@ -53,12 +53,12 @@ GetName:: ld hl, NamePointers add hl, de ld a, [hli] - ld [hSwapTemp + 1], a + ldh [hSwapTemp + 1], a ld a, [hl] - ld [hSwapTemp], a - ld a, [hSwapTemp] + ldh [hSwapTemp], a + ldh a, [hSwapTemp] ld h, a - ld a, [hSwapTemp + 1] + ldh a, [hSwapTemp + 1] ld l, a ld a, [wd0b5] ld b, a @@ -88,6 +88,6 @@ GetName:: pop bc pop hl pop af - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a ret diff --git a/home/npc_movement.asm b/home/npc_movement.asm new file mode 100644 index 00000000..4914d3df --- /dev/null +++ b/home/npc_movement.asm @@ -0,0 +1,54 @@ +; 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 + ldh a, [hLoadedROMBank] + push af + ld a, [wNPCMovementScriptBank] + ldh [hLoadedROMBank], a + ld [MBC1RomBank], a + ld a, [wNPCMovementScriptFunctionNum] + call CallFunctionInTable + pop af + ldh [hLoadedROMBank], a + ld [MBC1RomBank], a + ret + +.NPCMovementScriptPointerTables + dw PalletMovementScriptPointerTable + dw PewterMuseumGuyMovementScriptPointerTable + dw PewterGymGuyMovementScriptPointerTable +.playerStepOutFromDoor + farjp PlayerStepOutFromDoor + +EndNPCMovementScript:: + farjp _EndNPCMovementScript + +EmptyFunc2:: + ret diff --git a/home/oam.asm b/home/oam.asm new file mode 100644 index 00000000..8a940d97 --- /dev/null +++ b/home/oam.asm @@ -0,0 +1,36 @@ +; 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, HIGH(wOAMBuffer) + 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 diff --git a/home/overworld.asm b/home/overworld.asm index be4af6ee..0408bf32 100644 --- a/home/overworld.asm +++ b/home/overworld.asm @@ -1,14 +1,14 @@ HandleMidJump:: ; Handle the player jumping down ; a ledge in the overworld. - jpba _HandleMidJump + farjp _HandleMidJump EnterMap:: ; Load a new map. ld a, $ff ld [wJoyIgnore], a call LoadMapData - callba ClearVariablesOnEnterMap + farcall ClearVariablesOnEnterMap ld hl, wd72c bit 0, [hl] ; has the player already made 3 steps since the last battle? jr z, .skipGivingThreeStepsOfNoRandomBattles @@ -25,10 +25,10 @@ EnterMap:: and 1 << 4 | 1 << 3 ; fly warp or dungeon warp jr z, .didNotEnterUsingFlyWarpOrDungeonWarp res 3, [hl] - callba EnterMapAnim + farcall EnterMapAnim call UpdateSprites .didNotEnterUsingFlyWarpOrDungeonWarp - callba CheckForceBikeOrSurf ; handle currents in SF islands and forced bike riding in cycling road + farcall CheckForceBikeOrSurf ; handle currents in SF islands and forced bike riding in cycling road ld hl, wd72d res 5, [hl] call UpdateSprites @@ -50,7 +50,7 @@ OverworldLoopLessDelay:: and a jp nz, .moveAhead ; if the player sprite has not yet completed the walking animation call JoypadOverworld ; get joypad state (which is possibly simulated) - callba SafariZoneCheck + farcall SafariZoneCheck ld a, [wSafariZoneGameOver] and a jp nz, WarpFound2 @@ -67,16 +67,16 @@ OverworldLoopLessDelay:: ld a, [wd730] bit 7, a ; are we simulating button presses? jr z, .notSimulating - ld a, [hJoyHeld] + ldh a, [hJoyHeld] jr .checkIfStartIsPressed .notSimulating - ld a, [hJoyPressed] + ldh a, [hJoyPressed] .checkIfStartIsPressed bit 3, a ; start button jr z, .startButtonNotPressed ; if START is pressed xor a ; TEXT_START_MENU - ld [hSpriteIndexOrTextID], a + ldh [hSpriteIndexOrTextID], a jp .displayDialogue .startButtonNotPressed bit 0, a ; A button @@ -88,11 +88,11 @@ OverworldLoopLessDelay:: call IsPlayerCharacterBeingControlledByGame jr nz, .checkForOpponent call CheckForHiddenObjectOrBookshelfOrCardKeyDoor - ld a, [hItemAlreadyFound] + ldh a, [hItemAlreadyFound] and a jp z, OverworldLoop ; jump if a hidden object or bookshelf was found, but not if a card key door was found call IsSpriteOrSignInFrontOfPlayer - ld a, [hSpriteIndexOrTextID] + ldh a, [hSpriteIndexOrTextID] and a jp z, OverworldLoop .displayDialogue @@ -103,7 +103,7 @@ OverworldLoopLessDelay:: jr nz, .checkForOpponent bit 0, a jr nz, .checkForOpponent - aCoord 8, 9 + lda_coord 8, 9 ld [wTilePlayerStandingOn], a ; unused? call DisplayTextID ; display either the start menu or the NPC/sign text ld a, [wEnteringCableClub] @@ -145,7 +145,7 @@ OverworldLoopLessDelay:: jp OverworldLoop .checkIfDownButtonIsPressed - ld a, [hJoyHeld] ; current joypad state + ldh a, [hJoyHeld] ; current joypad state bit 7, a ; down button jr z, .checkIfUpButtonIsPressed ld a, 1 @@ -269,7 +269,7 @@ OverworldLoopLessDelay:: ld a, [wd736] bit 7, a jr z, .noSpinning - callba LoadSpinnerArrowTiles + farcall LoadSpinnerArrowTiles .noSpinning call UpdateSprites @@ -306,7 +306,7 @@ OverworldLoopLessDelay:: .doneStepCounting CheckEvent EVENT_IN_SAFARI_ZONE jr z, .notSafariZone - callba SafariZoneCheckSteps + farcall SafariZoneCheckSteps ld a, [wSafariZoneGameOver] and a jp nz, WarpFound2 @@ -332,7 +332,7 @@ OverworldLoopLessDelay:: set 5, [hl] set 6, [hl] xor a - ld [hJoyHeld], a + ldh [hJoyHeld], a ld a, [wCurMap] cp CINNABAR_GYM jr nz, .notCinnabarGym @@ -343,7 +343,7 @@ OverworldLoopLessDelay:: ld a, [wCurMap] cp OAKS_LAB jp z, .noFaintCheck ; no blacking out if the player lost to the rival in Oak's lab - callab AnyPartyAlive + callfar AnyPartyAlive ld a, d and a jr z, .allPokemonFainted @@ -368,7 +368,7 @@ NewBattle:: ld a, [wd72e] bit 4, a jr nz, .noBattle - jpba InitBattle + farjp InitBattle .noBattle and a ret @@ -381,7 +381,7 @@ DoBikeSpeedup:: ld a, [wCurMap] cp ROUTE_17 ; Cycling Road jr nz, .goFaster - ld a, [hJoyHeld] + ldh a, [hJoyHeld] and D_UP | D_LEFT | D_RIGHT ret nz .goFaster @@ -412,7 +412,7 @@ CheckWarpsNoCollisionLoop:: push bc ld hl, wd736 set 2, [hl] ; standing on warp flag - callba IsPlayerStandingOnDoorTileOrWarpTile + farcall IsPlayerStandingOnDoorTileOrWarpTile pop bc pop hl jr c, WarpFound1 ; jump if standing on door or warp @@ -431,7 +431,7 @@ CheckWarpsNoCollisionLoop:: call Joypad pop bc pop de - ld a, [hJoyHeld] + ldh a, [hJoyHeld] and D_DOWN | D_UP | D_LEFT | D_RIGHT jr z, CheckWarpsNoCollisionRetry2 ; if directional buttons aren't being pressed, do not pass through the warp jr WarpFound1 @@ -455,7 +455,7 @@ CheckWarpsCollision:: ld a, [hli] ld [wDestinationWarpID], a ld a, [hl] - ld [hWarpDestinationMap], a + ldh [hWarpDestinationMap], a jr WarpFound2 .retry1 inc hl @@ -477,7 +477,7 @@ WarpFound1:: ld a, [hli] ld [wDestinationWarpID], a ld a, [hli] - ld [hWarpDestinationMap], a + ldh [hWarpDestinationMap], a WarpFound2:: ld a, [wNumberOfWarps] @@ -492,7 +492,7 @@ WarpFound2:: ld [wLastMap], a ld a, [wCurMapWidth] ld [wUnusedD366], a ; not read - ld a, [hWarpDestinationMap] + ldh a, [hWarpDestinationMap] ld [wCurMap], a cp ROCK_TUNNEL_1F jr nz, .notRockTunnel @@ -506,12 +506,12 @@ WarpFound2:: ; for maps that can have the 0xFF destination map, which means to return to the outside map ; not all these maps are necessarily indoors, though .indoorMaps - ld a, [hWarpDestinationMap] ; destination map + ldh a, [hWarpDestinationMap] ; destination map cp $ff jr z, .goBackOutside ; if not going back to the previous map ld [wCurMap], a - callba IsPlayerStandingOnWarpPadOrHole + farcall IsPlayerStandingOnWarpPadOrHole ld a, [wStandingOnWarpPadOrHole] dec a ; is the player on a warp pad? jr nz, .notWarpPad @@ -678,8 +678,8 @@ CheckMapConnections:: ld b, SET_PAL_OVERWORLD call RunPaletteCommand ; Since the sprite set shouldn't change, this will just update VRAM slots at -; $C2XE without loading any tile patterns. - callba InitMapSprites +; x#SPRITESTATEDATA2_IMAGEBASEOFFSET without loading any tile patterns. + farcall InitMapSprites call LoadTileBlockMap jp OverworldLoopLessDelay @@ -688,7 +688,7 @@ CheckMapConnections:: ; function to play a sound when changing maps PlayMapChangeSound:: - aCoord 8, 8 ; upper left tile of the 4x4 square the player's sprite is standing on + lda_coord 8, 8 ; upper left tile of the 4x4 square the player's sprite is standing on cp $0b ; door tile in tileset 0 jr nz, .didNotGoThroughDoor ld a, SFX_GO_INSIDE @@ -747,7 +747,7 @@ ExtraWarpCheck:: jp Bankswitch MapEntryAfterBattle:: - callba IsPlayerStandingOnWarp ; for enabling warp testing after collisions + farcall IsPlayerStandingOnWarp ; for enabling warp testing after collisions ld a, [wMapPalOffset] and a jp z, GBFadeInFromWhite @@ -763,7 +763,7 @@ HandleBlackOut:: ld hl, wd72e res 5, [hl] ld a, BANK(ResetStatusAndHalveMoneyOnBlackout) ; also BANK(SpecialWarpIn) and BANK(SpecialEnterMap) - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a call ResetStatusAndHalveMoneyOnBlackout call SpecialWarpIn @@ -794,13 +794,13 @@ HandleFlyWarpOrDungeonWarp:: res 5, [hl] ; forced to ride bike call LeaveMapAnim ld a, BANK(SpecialWarpIn) - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a call SpecialWarpIn jp SpecialEnterMap LeaveMapAnim:: - jpba _LeaveMapAnim + farjp _LeaveMapAnim LoadPlayerSpriteGraphics:: ; Load sprite graphics based on whether the player is standing, biking, or surfing. @@ -813,7 +813,7 @@ LoadPlayerSpriteGraphics:: dec a jr z, .ridingBike - ld a, [hTilesetType] + ldh a, [hTilesetType] and a jr nz, .determineGraphics jr .startWalking @@ -899,9 +899,9 @@ LoadTileBlockMap:: ; a 3-byte border at the edges of the map is kept so that there is space for map connections ld hl, wOverworldMap ld a, [wCurMapWidth] - ld [hMapWidth], a + ldh [hMapWidth], a add MAP_BORDER * 2 ; east and west - ld [hMapStride], a ; map width + border + ldh [hMapStride], a ; map width + border ld b, 0 ld c, a ; make space for north border (next 3 lines) @@ -918,7 +918,7 @@ LoadTileBlockMap:: ld b, a .rowLoop ; copy one row each iteration push hl - ld a, [hMapWidth] ; map width (without border) + ldh a, [hMapWidth] ; map width (without border) ld c, a .rowInnerLoop ld a, [de] @@ -928,7 +928,7 @@ LoadTileBlockMap:: jr nz, .rowInnerLoop ; add the map width plus the border to the base address of the current row to get the next row's address pop hl - ld a, [hMapStride] ; map width + border + ldh a, [hMapStride] ; map width + border add l ld l, a jr nc, .noCarry @@ -950,9 +950,9 @@ LoadTileBlockMap:: ld a, [wNorthConnectionStripDest + 1] ld d, a ld a, [wNorthConnectionStripWidth] - ld [hNorthSouthConnectionStripWidth], a + ldh [hNorthSouthConnectionStripWidth], a ld a, [wNorthConnectedMapWidth] - ld [hNorthSouthConnectedMapWidth], a + ldh [hNorthSouthConnectedMapWidth], a call LoadNorthSouthConnectionsTileMap .southConnection ld a, [wMapConn2Ptr] @@ -968,9 +968,9 @@ LoadTileBlockMap:: ld a, [wSouthConnectionStripDest + 1] ld d, a ld a, [wSouthConnectionStripWidth] - ld [hNorthSouthConnectionStripWidth], a + ldh [hNorthSouthConnectionStripWidth], a ld a, [wSouthConnectedMapWidth] - ld [hNorthSouthConnectedMapWidth], a + ldh [hNorthSouthConnectedMapWidth], a call LoadNorthSouthConnectionsTileMap .westConnection ld a, [wMapConn3Ptr] @@ -988,7 +988,7 @@ LoadTileBlockMap:: ld a, [wWestConnectionStripHeight] ld b, a ld a, [wWestConnectedMapWidth] - ld [hEastWestConnectedMapWidth], a + ldh [hEastWestConnectedMapWidth], a call LoadEastWestConnectionsTileMap .eastConnection ld a, [wMapConn4Ptr] @@ -1006,7 +1006,7 @@ LoadTileBlockMap:: ld a, [wEastConnectionStripHeight] ld b, a ld a, [wEastConnectedMapWidth] - ld [hEastWestConnectedMapWidth], a + ldh [hEastWestConnectedMapWidth], a call LoadEastWestConnectionsTileMap .done ret @@ -1016,7 +1016,7 @@ LoadNorthSouthConnectionsTileMap:: .loop push de push hl - ld a, [hNorthSouthConnectionStripWidth] + ldh a, [hNorthSouthConnectionStripWidth] ld b, a .innerLoop ld a, [hli] @@ -1026,7 +1026,7 @@ LoadNorthSouthConnectionsTileMap:: jr nz, .innerLoop pop hl pop de - ld a, [hNorthSouthConnectedMapWidth] + ldh a, [hNorthSouthConnectedMapWidth] add l ld l, a jr nc, .noCarry1 @@ -1055,7 +1055,7 @@ LoadEastWestConnectionsTileMap:: jr nz, .innerLoop pop de pop hl - ld a, [hEastWestConnectedMapWidth] + ldh a, [hEastWestConnectedMapWidth] add l ld l, a jr nc, .noCarry1 @@ -1077,7 +1077,7 @@ LoadEastWestConnectionsTileMap:: ; if not, [hSpriteIndexOrTextID] is set to 0 IsSpriteOrSignInFrontOfPlayer:: xor a - ld [hSpriteIndexOrTextID], a + ldh [hSpriteIndexOrTextID], a ld a, [wNumSigns] and a jr z, .extendRangeOverCounter @@ -1107,7 +1107,7 @@ IsSpriteOrSignInFrontOfPlayer:: dec c add hl, bc ld a, [hl] - ld [hSpriteIndexOrTextID], a ; store sign text ID + ldh [hSpriteIndexOrTextID], a ; store sign text ID pop bc pop hl ret @@ -1210,10 +1210,10 @@ IsSpriteInFrontOfPlayer2:: ld a, l and $f0 inc a - ld l, a ; hl = $c1x1 + ld l, a ; hl = x#SPRITESTATEDATA1_MOVEMENTSTATUS set 7, [hl] ; set flag to make the sprite face the player ld a, e - ld [hSpriteIndexOrTextID], a + ldh [hSpriteIndexOrTextID], a ret ; function to check if the player will jump down a ledge and check if the tile ahead is passable (when not surfing) @@ -1232,9 +1232,9 @@ CollisionCheckOnLand:: and d ; check if a sprite is in the direction the player is trying to go jr nz, .collision xor a - ld [hSpriteIndexOrTextID], a + ldh [hSpriteIndexOrTextID], a call IsSpriteInFrontOfPlayer ; check for sprite collisions again? when does the above check fail to detect a sprite collision? - ld a, [hSpriteIndexOrTextID] + ldh a, [hSpriteIndexOrTextID] and a ; was there a sprite collision? jr nz, .collision ; if no sprite collision @@ -1286,7 +1286,7 @@ CheckForJumpingAndTilePairCollisions:: predef GetTileAndCoordsInFrontOfPlayer ; get the tile in front of the player push de push bc - callba HandleLedges ; check if the player is trying to jump a ledge + farcall HandleLedges ; check if the player is trying to jump a ledge pop bc pop de pop hl @@ -1297,7 +1297,7 @@ CheckForJumpingAndTilePairCollisions:: ; if not jumping CheckForTilePairCollisions2:: - aCoord 8, 9 ; tile the player is on + lda_coord 8, 9 ; tile the player is on ld [wTilePlayerStandingOn], a CheckForTilePairCollisions:: @@ -1372,10 +1372,10 @@ TilePairCollisionsWater:: ; this builds a tile map from the tile block map based on the current X/Y coordinates of the player's character LoadCurrentMapView:: - ld a, [hLoadedROMBank] + ldh a, [hLoadedROMBank] push af ld a, [wTilesetBank] ; tile data ROM bank - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a ; switch to ROM bank that contains tile data ld a, [wCurrentTileBlockMapViewPointer] ; address of upper left corner of current map view ld e, a @@ -1438,7 +1438,7 @@ LoadCurrentMapView:: ld bc, $2 add hl, bc .copyToVisibleAreaBuffer - coord de, 0, 0 ; base address for the tiles that are directly transferred to VRAM during V-blank + decoord 0, 0 ; base address for the tiles that are directly transferred to VRAM during V-blank ld b, SCREEN_HEIGHT .rowLoop2 ld c, SCREEN_WIDTH @@ -1457,7 +1457,7 @@ LoadCurrentMapView:: dec b jr nz, .rowLoop2 pop af - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a ; restore previous ROM bank ret @@ -1627,12 +1627,12 @@ AdvancePlayerSprite:: ld c, a sla b sla c - ld a, [hSCY] + ldh a, [hSCY] add b - ld [hSCY], a ; update background scroll Y - ld a, [hSCX] + ldh [hSCY], a ; update background scroll Y + ldh a, [hSCX] add c - ld [hSCX], a ; update background scroll X + ldh [hSCX], a ; update background scroll X ; shift all the sprites in the direction opposite of the player's motion ; so that the player appears to move relative to them ld hl, wSprite01StateData1YPixels @@ -1711,14 +1711,14 @@ MoveTileBlockMapPointerNorth:: ; the portion of the map that was newly exposed due to the player's movement ScheduleNorthRowRedraw:: - coord hl, 0, 0 + hlcoord 0, 0 call CopyToRedrawRowOrColumnSrcTiles ld a, [wMapViewVRAMPointer] - ld [hRedrawRowOrColumnDest], a + ldh [hRedrawRowOrColumnDest], a ld a, [wMapViewVRAMPointer + 1] - ld [hRedrawRowOrColumnDest + 1], a + ldh [hRedrawRowOrColumnDest + 1], a ld a, REDRAW_ROW - ld [hRedrawRowOrColumnMode], a + ldh [hRedrawRowOrColumnMode], a ret CopyToRedrawRowOrColumnSrcTiles:: @@ -1733,7 +1733,7 @@ CopyToRedrawRowOrColumnSrcTiles:: ret ScheduleSouthRowRedraw:: - coord hl, 0, 16 + hlcoord 0, 16 call CopyToRedrawRowOrColumnSrcTiles ld a, [wMapViewVRAMPointer] ld l, a @@ -1744,15 +1744,15 @@ ScheduleSouthRowRedraw:: ld a, h and $03 or $98 - ld [hRedrawRowOrColumnDest + 1], a + ldh [hRedrawRowOrColumnDest + 1], a ld a, l - ld [hRedrawRowOrColumnDest], a + ldh [hRedrawRowOrColumnDest], a ld a, REDRAW_ROW - ld [hRedrawRowOrColumnMode], a + ldh [hRedrawRowOrColumnMode], a ret ScheduleEastColumnRedraw:: - coord hl, 18, 0 + hlcoord 18, 0 call ScheduleColumnRedrawHelper ld a, [wMapViewVRAMPointer] ld c, a @@ -1762,11 +1762,11 @@ ScheduleEastColumnRedraw:: add 18 and $1f or b - ld [hRedrawRowOrColumnDest], a + ldh [hRedrawRowOrColumnDest], a ld a, [wMapViewVRAMPointer + 1] - ld [hRedrawRowOrColumnDest + 1], a + ldh [hRedrawRowOrColumnDest + 1], a ld a, REDRAW_COL - ld [hRedrawRowOrColumnMode], a + ldh [hRedrawRowOrColumnMode], a ret ScheduleColumnRedrawHelper:: @@ -1790,14 +1790,14 @@ ScheduleColumnRedrawHelper:: ret ScheduleWestColumnRedraw:: - coord hl, 0, 0 + hlcoord 0, 0 call ScheduleColumnRedrawHelper ld a, [wMapViewVRAMPointer] - ld [hRedrawRowOrColumnDest], a + ldh [hRedrawRowOrColumnDest], a ld a, [wMapViewVRAMPointer + 1] - ld [hRedrawRowOrColumnDest + 1], a + ldh [hRedrawRowOrColumnDest + 1], a ld a, REDRAW_COL - ld [hRedrawRowOrColumnMode], a + ldh [hRedrawRowOrColumnMode], a ret ; function to write the tiles that make up a tile block to memory @@ -1855,17 +1855,17 @@ JoypadOverworld:: ld a, [wCurMap] cp ROUTE_17 ; Cycling Road jr nz, .notForcedDownwards - ld a, [hJoyHeld] + ldh a, [hJoyHeld] and D_DOWN | D_UP | D_LEFT | D_RIGHT | B_BUTTON | A_BUTTON jr nz, .notForcedDownwards ld a, D_DOWN - ld [hJoyHeld], a ; on the cycling road, if there isn't a trainer and the player isn't pressing buttons, simulate a down press + ldh [hJoyHeld], a ; on the cycling road, if there isn't a trainer and the player isn't pressing buttons, simulate a down press .notForcedDownwards ld a, [wd730] bit 7, a ret z ; if simulating button presses - ld a, [hJoyHeld] + ldh a, [hJoyHeld] ld b, a ld a, [wOverrideSimulatedJoypadStatesMask] ; bit mask for button presses that override simulated ones and b @@ -1882,11 +1882,11 @@ JoypadOverworld:: inc h .noCarry ld a, [hl] - ld [hJoyHeld], a ; store simulated button press in joypad state + ldh [hJoyHeld], a ; store simulated button press in joypad state and a ret nz - ld [hJoyPressed], a - ld [hJoyReleased], a + ldh [hJoyPressed], a + ldh [hJoyReleased], a ret ; if done simulating button presses @@ -1896,7 +1896,7 @@ JoypadOverworld:: ld [wSimulatedJoypadStatesIndex], a ld [wSimulatedJoypadStatesEnd], a ld [wJoyIgnore], a - ld [hJoyHeld], a + ldh [hJoyHeld], a ld hl, wd736 ld a, [hl] and $f8 @@ -1977,11 +1977,11 @@ RunMapScript:: push hl push de push bc - callba TryPushingBoulder + farcall TryPushingBoulder ld a, [wFlags_0xcd60] bit 1, a ; play boulder dust animation jr z, .afterBoulderEffect - callba DoBoulderDustAnimation + farcall DoBoulderDustAnimation .afterBoulderEffect pop bc pop de @@ -2032,7 +2032,7 @@ LoadPlayerSpriteGraphicsCommon:: ; function to load data from the map header LoadMapHeader:: - callba MarkTownVisitedAndLoadMissableObjects + farcall MarkTownVisitedAndLoadMissableObjects ld a, [wCurMapTileset] ld [wUnusedD119], a ld a, [wCurMap] @@ -2041,7 +2041,7 @@ LoadMapHeader:: ld b, a res 7, a ld [wCurMapTileset], a - ld [hPreviousTileset], a + ldh [hPreviousTileset], a bit 7, b ret nz ld hl, MapHeaderPointers @@ -2134,9 +2134,9 @@ LoadMapHeader:: ld c, a ld de, wSignTextIDs ld a, d - ld [hSignCoordPointer], a + ldh [hSignCoordPointer], a ld a, e - ld [hSignCoordPointer + 1], a + ldh [hSignCoordPointer + 1], a ld de, wSignCoords .signLoop ld a, [hli] @@ -2146,17 +2146,17 @@ LoadMapHeader:: ld [de], a inc de push de - ld a, [hSignCoordPointer] + ldh a, [hSignCoordPointer] ld d, a - ld a, [hSignCoordPointer + 1] + ldh a, [hSignCoordPointer + 1] ld e, a ld a, [hli] ld [de], a inc de ld a, d - ld [hSignCoordPointer], a + ldh [hSignCoordPointer], a ld a, e - ld [hSignCoordPointer + 1], a + ldh [hSignCoordPointer + 1], a pop de dec c jr nz, .signLoop @@ -2167,7 +2167,7 @@ LoadMapHeader:: ld a, [hli] ld [wNumSprites], a ; save the number of sprites push hl -; zero C110-C1FF and C210-C2FF +; zero out sprite state data for sprites 01-15 ld hl, wSprite01StateData1 ld de, wSprite01StateData2 xor a @@ -2178,7 +2178,7 @@ LoadMapHeader:: inc e dec b jr nz, .zeroSpriteDataLoop -; initialize all C100-C1FF sprite entries to disabled (other than player's) +; disable SPRITESTATEDATA1_IMAGEINDEX (set to $ff) for sprites 01-15 ld hl, wSprite01StateData1ImageIndex ld de, $10 ld c, $0f @@ -2196,38 +2196,38 @@ LoadMapHeader:: ld c, $00 .loadSpriteLoop ld a, [hli] - ld [de], a ; store picture ID at C1X0 + ld [de], a ; x#SPRITESTATEDATA1_PICTUREID inc d ld a, $04 add e ld e, a ld a, [hli] - ld [de], a ; store Y position at C2X4 + ld [de], a ; x#SPRITESTATEDATA2_MAPY inc e ld a, [hli] - ld [de], a ; store X position at C2X5 + ld [de], a ; x#SPRITESTATEDATA2_MAPX inc e ld a, [hli] - ld [de], a ; store movement byte 1 at C2X6 + ld [de], a ; x#SPRITESTATEDATA2_MOVEMENTBYTE1 ld a, [hli] - ld [hLoadSpriteTemp1], a ; save movement byte 2 + ldh [hLoadSpriteTemp1], a ; save movement byte 2 ld a, [hli] - ld [hLoadSpriteTemp2], a ; save text ID and flags byte + ldh [hLoadSpriteTemp2], a ; save text ID and flags byte push bc push hl ld b, $00 ld hl, wMapSpriteData add hl, bc - ld a, [hLoadSpriteTemp1] + ldh a, [hLoadSpriteTemp1] ld [hli], a ; store movement byte 2 in byte 0 of sprite entry - ld a, [hLoadSpriteTemp2] + ldh a, [hLoadSpriteTemp2] ld [hl], a ; this appears pointless, since the value is overwritten immediately after - ld a, [hLoadSpriteTemp2] - ld [hLoadSpriteTemp1], a + ldh a, [hLoadSpriteTemp2] + ldh [hLoadSpriteTemp1], a and $3f ld [hl], a ; store text ID in byte 1 of sprite entry pop hl - ld a, [hLoadSpriteTemp1] + ldh a, [hLoadSpriteTemp1] bit 6, a jr nz, .trainerSprite bit 7, a @@ -2235,25 +2235,25 @@ LoadMapHeader:: jr .regularSprite .trainerSprite ld a, [hli] - ld [hLoadSpriteTemp1], a ; save trainer class + ldh [hLoadSpriteTemp1], a ; save trainer class ld a, [hli] - ld [hLoadSpriteTemp2], a ; save trainer number (within class) + ldh [hLoadSpriteTemp2], a ; save trainer number (within class) push hl ld hl, wMapSpriteExtraData add hl, bc - ld a, [hLoadSpriteTemp1] + ldh a, [hLoadSpriteTemp1] ld [hli], a ; store trainer class in byte 0 of the entry - ld a, [hLoadSpriteTemp2] + ldh a, [hLoadSpriteTemp2] ld [hl], a ; store trainer number in byte 1 of the entry pop hl jr .nextSprite .itemBallSprite ld a, [hli] - ld [hLoadSpriteTemp1], a ; save item number + ldh [hLoadSpriteTemp1], a ; save item number push hl ld hl, wMapSpriteExtraData add hl, bc - ld a, [hLoadSpriteTemp1] + ldh a, [hLoadSpriteTemp1] ld [hli], a ; store item number in byte 0 of the entry xor a ld [hl], a ; zero byte 1, since it is not used @@ -2280,7 +2280,7 @@ LoadMapHeader:: jp nz, .loadSpriteLoop .finishUp predef LoadTilesetHeader - callab LoadWildData + callfar LoadWildData pop hl ; restore hl from before going to the warp/sign/sprite data (this value was saved for seemingly no purpose) ld a, [wCurMapHeight] ; map height in 4x4 tile blocks add a ; double it @@ -2291,10 +2291,10 @@ LoadMapHeader:: ld a, [wCurMap] ld c, a ld b, $00 - ld a, [hLoadedROMBank] + ldh a, [hLoadedROMBank] push af ld a, BANK(MapSongBanks) - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a ld hl, MapSongBanks add hl, bc @@ -2304,7 +2304,7 @@ LoadMapHeader:: ld a, [hl] ld [wMapMusicROMBank], a ; music 2 pop af - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a ret @@ -2322,27 +2322,27 @@ CopyMapConnectionHeader:: ; function to load map data LoadMapData:: - ld a, [hLoadedROMBank] + ldh a, [hLoadedROMBank] push af call DisableLCD ld a, $98 ld [wMapViewVRAMPointer + 1], a xor a ld [wMapViewVRAMPointer], a - ld [hSCY], a - ld [hSCX], a + ldh [hSCY], a + ldh [hSCX], a ld [wWalkCounter], a ld [wUnusedD119], a ld [wWalkBikeSurfStateCopy], a ld [wSpriteSetID], a call LoadTextBoxTilePatterns call LoadMapHeader - callba InitMapSprites ; load tile pattern data for sprites + farcall InitMapSprites ; load tile pattern data for sprites call LoadTileBlockMap call LoadTilesetTilePatternData call LoadCurrentMapView ; copy current map view to VRAM - coord hl, 0, 0 + hlcoord 0, 0 ld de, vBGMap0 ld b, 18 .vramCopyLoop @@ -2377,7 +2377,7 @@ LoadMapData:: call PlayDefaultMusicFadeOutCurrent .restoreRomBank pop af - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a ret @@ -2393,10 +2393,10 @@ SwitchToMapRomBank:: ld hl, MapHeaderBanks add hl, bc ld a, [hl] - ld [hMapROMBank], a ; save map ROM bank + ldh [hMapROMBank], a ; save map ROM bank call BankswitchBack - ld a, [hMapROMBank] - ld [hLoadedROMBank], a + ldh a, [hMapROMBank] + ldh [hLoadedROMBank], a ld [MBC1RomBank], a ; switch to map ROM bank pop bc pop hl @@ -2421,3 +2421,54 @@ ForceBikeOrSurf:: ld hl, LoadPlayerSpriteGraphics call Bankswitch jp PlayDefaultMusic ; update map/player state? + +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 + + ldh a, [hJoyHeld] + cp D_UP + SELECT + B_BUTTON + jr z, .input + + ldh 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 + ldh a, [hLoadedROMBank] + push af + ld a, [wPredefParentBank] + ldh [hLoadedROMBank], 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 + ldh [hLoadedROMBank], a + ld [MBC1RomBank], a + ret diff --git a/home/palettes.asm b/home/palettes.asm new file mode 100644 index 00000000..08dcdc85 --- /dev/null +++ b/home/palettes.asm @@ -0,0 +1,57 @@ +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 + ldh [rBGP], a + ld a, %11010000 ; 3100 + ldh [rOBP0], a + ret + +GBPalWhiteOut:: +; White out all palettes. + xor a + ldh [rBGP], a + ldh [rOBP0], a + ldh [rOBP1], a + ret + +RunDefaultPaletteCommand:: + ld b, SET_PAL_DEFAULT +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 diff --git a/home/pathfinding.asm b/home/pathfinding.asm new file mode 100644 index 00000000..aca5a763 --- /dev/null +++ b/home/pathfinding.asm @@ -0,0 +1,65 @@ +; 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 [hSpriteIndex] 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 diff --git a/home/pics.asm b/home/pics.asm index c6d99cbb..ef668620 100644 --- a/home/pics.asm +++ b/home/pics.asm @@ -63,7 +63,7 @@ LoadMonFrontSprite:: LoadUncompressedSpriteData:: push de and $f - ld [hSpriteWidth], a ; each byte contains 8 pixels (in 1bpp), so tiles=bytes for width + ldh [hSpriteWidth], a ; each byte contains 8 pixels (in 1bpp), so tiles=bytes for width ld b, a ld a, $7 sub b ; 7-w @@ -74,7 +74,7 @@ LoadUncompressedSpriteData:: add a add a sub b ; 7*((8-w)/2) ; skip for horizontal center (in tiles) - ld [hSpriteOffset], a + ldh [hSpriteOffset], a ld a, c swap a and $f @@ -82,16 +82,16 @@ LoadUncompressedSpriteData:: add a add a add a ; 8*tiles is height in bytes - ld [hSpriteHeight], a + ldh [hSpriteHeight], a ld a, $7 sub b ; 7-h ; skip for vertical center (in tiles, relative to current column) ld b, a - ld a, [hSpriteOffset] + ldh a, [hSpriteOffset] 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 [hSpriteOffset], a + ldh [hSpriteOffset], a xor a ld [MBC1SRamBank], a ld hl, sSpriteBuffer0 @@ -110,15 +110,15 @@ LoadUncompressedSpriteData:: ; 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, [hSpriteOffset] + ldh a, [hSpriteOffset] ld b, $0 ld c, a add hl, bc - ld a, [hSpriteWidth] + ldh a, [hSpriteWidth] .columnLoop push af push hl - ld a, [hSpriteHeight] + ldh a, [hSpriteHeight] ld c, a .columnInnerLoop ld a, [de] @@ -157,7 +157,7 @@ InterlaceMergeSpriteBuffers:: 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 [hSpriteInterlaceCounter], a + ldh [hSpriteInterlaceCounter], a .interlaceLoop ld a, [de] dec de @@ -171,9 +171,9 @@ InterlaceMergeSpriteBuffers:: ld a, [bc] dec bc ld [hld], a ; write byte of source 1 - ld a, [hSpriteInterlaceCounter] + ldh a, [hSpriteInterlaceCounter] dec a - ld [hSpriteInterlaceCounter], a + ldh [hSpriteInterlaceCounter], a jr nz, .interlaceLoop ld a, [wSpriteFlipped] and a @@ -191,6 +191,6 @@ InterlaceMergeSpriteBuffers:: pop hl ld de, sSpriteBuffer1 ld c, (2*SPRITEBUFFERSIZE)/16 ; $31, number of 16 byte chunks to be copied - ld a, [hLoadedROMBank] + ldh a, [hLoadedROMBank] ld b, a jp CopyVideoData diff --git a/home/pokemon.asm b/home/pokemon.asm index 539632d4..d018843e 100644 --- a/home/pokemon.asm +++ b/home/pokemon.asm @@ -81,7 +81,7 @@ DrawHPBar:: ; wLoadedMon = base address of pokemon data ; wMonHeader = base address of base stats LoadMonData:: - jpab LoadMonData_ + jpfar LoadMonData_ OverwritewMoves:: ; Write c to [wMoves + b]. Unused. @@ -122,18 +122,18 @@ LoadFrontSpriteByMonIndex:: ld de, vFrontPic call LoadMonFrontSprite pop hl - ld a, [hLoadedROMBank] + ldh a, [hLoadedROMBank] push af ld a, BANK(CopyUncompressedPicToHL) - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a xor a - ld [hStartTileID], a + ldh [hStartTileID], a call CopyUncompressedPicToHL xor a ld [wSpriteFlipped], a pop af - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a ret @@ -175,10 +175,10 @@ GetCryData:: ret DisplayPartyMenu:: - ld a, [hTilesetType] + ldh a, [hTilesetType] push af xor a - ld [hTilesetType], a + ldh [hTilesetType], a call GBPalWhiteOutWithDelay3 call ClearSprites call PartyMenuInit @@ -186,10 +186,10 @@ DisplayPartyMenu:: jp HandlePartyMenuInput GoBackToPartyMenu:: - ld a, [hTilesetType] + ldh a, [hTilesetType] push af xor a - ld [hTilesetType], a + ldh [hTilesetType], a call PartyMenuInit call RedrawPartyMenu jp HandlePartyMenuInput @@ -251,7 +251,7 @@ HandlePartyMenuInput:: and a jp nz, .swappingPokemon pop af - ld [hTilesetType], a + ldh [hTilesetType], a bit 1, b jr nz, .noPokemonChosen ld a, [wPartyCount] @@ -277,7 +277,7 @@ HandlePartyMenuInput:: 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 + farcall ErasePartyMenuCursors xor a ld [wMenuItemToSwap], a ld [wPartyMenuTypeOrMessageID], a @@ -286,7 +286,7 @@ HandlePartyMenuInput:: .handleSwap ld a, [wCurrentMenuItem] ld [wWhichPokemon], a - callba SwitchPartyMon + farcall SwitchPartyMon jr HandlePartyMenuInput DrawPartyMenu:: @@ -325,15 +325,15 @@ PrintStatusCondition:: ret PrintStatusConditionNotFainted:: - ld a, [hLoadedROMBank] + ldh a, [hLoadedROMBank] push af ld a, BANK(PrintStatusAilment) - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a call PrintStatusAilment ; print status condition pop bc ld a, b - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a ret @@ -382,10 +382,10 @@ GetwMoves:: ; INPUT: ; [wd0b5] = pokemon ID GetMonHeader:: - ld a, [hLoadedROMBank] + ldh a, [hLoadedROMBank] push af ld a, BANK(BaseStats) - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a push bc push de @@ -440,7 +440,7 @@ GetMonHeader:: pop de pop bc pop af - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a ret diff --git a/home/predef.asm b/home/predef.asm index 4f0c37d9..69aa7347 100644 --- a/home/predef.asm +++ b/home/predef.asm @@ -8,18 +8,18 @@ Predef:: ; A hack for LoadDestinationWarpPosition. ; See LoadTilesetHeader (predef $19). - ld a, [hLoadedROMBank] + ldh a, [hLoadedROMBank] ld [wPredefParentBank], a push af ld a, BANK(GetPredefPointer) - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a call GetPredefPointer ld a, [wPredefBank] - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a ld de, .done @@ -28,7 +28,7 @@ Predef:: .done pop af - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a ret diff --git a/home/predef_text.asm b/home/predef_text.asm new file mode 100644 index 00000000..b494a2c8 --- /dev/null +++ b/home/predef_text.asm @@ -0,0 +1,28 @@ +PrintPredefTextID:: + ldh [hSpriteIndexOrTextID], a + ld hl, TextPredefs + call SetMapTextPointer + ld hl, wTextPredefFlag + set 0, [hl] + call DisplayTextID + +RestoreMapTextPointer:: + ld hl, wMapTextPtr + ldh a, [hSavedMapTextPtr] + ld [hli], a + ldh a, [hSavedMapTextPtr + 1] + ld [hl], a + ret + +SetMapTextPointer:: + ld a, [wMapTextPtr] + ldh [hSavedMapTextPtr], a + ld a, [wMapTextPtr + 1] + ldh [hSavedMapTextPtr + 1], a + ld a, l + ld [wMapTextPtr], a + ld a, h + ld [wMapTextPtr + 1], a + ret + +INCLUDE "data/text_predef_pointers.asm" diff --git a/home/print_num.asm b/home/print_num.asm index f7ea2174..e2628b1f 100644 --- a/home/print_num.asm +++ b/home/print_num.asm @@ -6,9 +6,9 @@ PrintNumber:: ; in bits 7 and 6 of b respectively. push bc xor a - ld [hPastLeadingZeros], a - ld [hNumToPrint], a - ld [hNumToPrint + 1], a + ldh [hPastLeadingZeros], a + ldh [hNumToPrint], a + ldh [hNumToPrint + 1], a ld a, b and $f cp 1 @@ -17,26 +17,26 @@ PrintNumber:: jr z, .word .long ld a, [de] - ld [hNumToPrint], a + ldh [hNumToPrint], a inc de ld a, [de] - ld [hNumToPrint + 1], a + ldh [hNumToPrint + 1], a inc de ld a, [de] - ld [hNumToPrint + 2], a + ldh [hNumToPrint + 2], a jr .start .word ld a, [de] - ld [hNumToPrint + 1], a + ldh [hNumToPrint + 1], a inc de ld a, [de] - ld [hNumToPrint + 2], a + ldh [hNumToPrint + 2], a jr .start .byte ld a, [de] - ld [hNumToPrint + 2], a + ldh [hNumToPrint + 2], a .start push de @@ -66,17 +66,17 @@ IF (\1) / $10000 ELSE xor a ENDC - ld [hPowerOf10 + 0], a + ldh [hPowerOf10 + 0], a IF (\1) / $100 ld a, \1 / $100 % $100 ELSE xor a ENDC - ld [hPowerOf10 + 1], a + ldh [hPowerOf10 + 1], a ld a, \1 / $1 % $100 - ld [hPowerOf10 + 2], a + ldh [hPowerOf10 + 2], a call .PrintDigit call .NextDigit @@ -90,7 +90,7 @@ ENDM .tens ld c, 0 - ld a, [hNumToPrint + 2] + ldh a, [hNumToPrint + 2] .mod cp 10 jr c, .ok @@ -100,9 +100,9 @@ ENDM .ok ld b, a - ld a, [hPastLeadingZeros] + ldh a, [hPastLeadingZeros] or c - ld [hPastLeadingZeros], a + ldh [hPastLeadingZeros], a jr nz, .past call .PrintLeadingZero jr .next @@ -127,74 +127,74 @@ ENDM ; Print the quotient, and keep the modulus. ld c, 0 .loop - ld a, [hPowerOf10] + ldh a, [hPowerOf10] ld b, a - ld a, [hNumToPrint] - ld [hSavedNumToPrint], a + ldh a, [hNumToPrint] + ldh [hSavedNumToPrint], a cp b jr c, .underflow0 sub b - ld [hNumToPrint], a - ld a, [hPowerOf10 + 1] + ldh [hNumToPrint], a + ldh a, [hPowerOf10 + 1] ld b, a - ld a, [hNumToPrint + 1] - ld [hSavedNumToPrint + 1], a + ldh a, [hNumToPrint + 1] + ldh [hSavedNumToPrint + 1], a cp b jr nc, .noborrow1 - ld a, [hNumToPrint] + ldh a, [hNumToPrint] or 0 jr z, .underflow1 dec a - ld [hNumToPrint], a - ld a, [hNumToPrint + 1] + ldh [hNumToPrint], a + ldh a, [hNumToPrint + 1] .noborrow1 sub b - ld [hNumToPrint + 1], a - ld a, [hPowerOf10 + 2] + ldh [hNumToPrint + 1], a + ldh a, [hPowerOf10 + 2] ld b, a - ld a, [hNumToPrint + 2] - ld [hSavedNumToPrint + 2], a + ldh a, [hNumToPrint + 2] + ldh [hSavedNumToPrint + 2], a cp b jr nc, .noborrow2 - ld a, [hNumToPrint + 1] + ldh a, [hNumToPrint + 1] and a jr nz, .borrowed - ld a, [hNumToPrint] + ldh a, [hNumToPrint] and a jr z, .underflow2 dec a - ld [hNumToPrint], a + ldh [hNumToPrint], a xor a .borrowed dec a - ld [hNumToPrint + 1], a - ld a, [hNumToPrint + 2] + ldh [hNumToPrint + 1], a + ldh a, [hNumToPrint + 2] .noborrow2 sub b - ld [hNumToPrint + 2], a + ldh [hNumToPrint + 2], a inc c jr .loop .underflow2 - ld a, [hSavedNumToPrint + 1] - ld [hNumToPrint + 1], a + ldh a, [hSavedNumToPrint + 1] + ldh [hNumToPrint + 1], a .underflow1 - ld a, [hSavedNumToPrint] - ld [hNumToPrint], a + ldh a, [hSavedNumToPrint] + ldh [hNumToPrint], a .underflow0 - ld a, [hPastLeadingZeros] + ldh a, [hPastLeadingZeros] or c jr z, .PrintLeadingZero ld a, "0" add c ld [hl], a - ld [hPastLeadingZeros], a + ldh [hPastLeadingZeros], a ret .PrintLeadingZero: @@ -211,7 +211,7 @@ ENDM jr nz, .inc bit BIT_LEFT_ALIGN, d jr z, .inc - ld a, [hPastLeadingZeros] + ldh a, [hPastLeadingZeros] and a ret z .inc diff --git a/home/print_text.asm b/home/print_text.asm new file mode 100644 index 00000000..049ddfb4 --- /dev/null +++ b/home/print_text.asm @@ -0,0 +1,45 @@ +; 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 + ldh [hFrameCounter], a + jr .checkButtons +.waitOneFrame + ld a, 1 + ldh [hFrameCounter], a +.checkButtons + call Joypad + ldh 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 + ldh a, [hFrameCounter] + and a + jr nz, .checkButtons +.done + pop bc + pop de + pop hl + ret diff --git a/home/random.asm b/home/random.asm new file mode 100644 index 00000000..33a24425 --- /dev/null +++ b/home/random.asm @@ -0,0 +1,12 @@ +Random:: +; Return a random number in a. +; For battles, use BattleRandom. + push hl + push de + push bc + farcall Random_ + ldh a, [hRandomAdd] + pop bc + pop de + pop hl + ret diff --git a/home/reload_sprites.asm b/home/reload_sprites.asm new file mode 100644 index 00000000..8a08d64d --- /dev/null +++ b/home/reload_sprites.asm @@ -0,0 +1,19 @@ +; 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 + farcall InitMapSprites + call EnableLCD + pop hl + pop af + ld [hl], a + call LoadPlayerSpriteGraphics + call LoadFontTilePatterns + jp UpdateSprites diff --git a/home/reload_tiles.asm b/home/reload_tiles.asm new file mode 100644 index 00000000..6228395c --- /dev/null +++ b/home/reload_tiles.asm @@ -0,0 +1,41 @@ +; reloads text box tile patterns, current map view, and tileset tile patterns +ReloadMapData:: + ldh a, [hLoadedROMBank] + push af + ld a, [wCurMap] + call SwitchToMapRomBank + call DisableLCD + call LoadTextBoxTilePatterns + call LoadCurrentMapView + call LoadTilesetTilePatternData + call EnableLCD + pop af + ldh [hLoadedROMBank], a + ld [MBC1RomBank], a + ret + +; reloads tileset tile patterns +ReloadTilesetTilePatterns:: + ldh a, [hLoadedROMBank] + push af + ld a, [wCurMap] + call SwitchToMapRomBank + call DisableLCD + call LoadTilesetTilePatternData + call EnableLCD + pop af + ldh [hLoadedROMBank], a + ld [MBC1RomBank], a + ret + +; shows the town map and lets the player choose a destination to fly to +ChooseFlyDestination:: + ld hl, wd72e + res 4, [hl] + farjp LoadTownMap_Fly + +; causes the text box to close without waiting for a button press after displaying text +DisableWaitingAfterTextDisplay:: + ld a, $01 + ld [wDoNotWaitForButtonPressAfterDisplayingText], a + ret diff --git a/home/reset_player_sprite.asm b/home/reset_player_sprite.asm new file mode 100644 index 00000000..72df31a1 --- /dev/null +++ b/home/reset_player_sprite.asm @@ -0,0 +1,20 @@ +ResetPlayerSpriteData:: + ld hl, wSpriteStateData1 + call ResetPlayerSpriteData_ClearSpriteData + ld hl, wSpriteStateData2 + call ResetPlayerSpriteData_ClearSpriteData + ld a, $1 + ld [wSpritePlayerStateData1PictureID], a + ld [wSpritePlayerStateData2ImageBaseOffset], a + ld hl, wSpritePlayerStateData1YPixels + 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 + jp FillMemory diff --git a/home/serial.asm b/home/serial.asm index 6c412239..bd984d4f 100644 --- a/home/serial.asm +++ b/home/serial.asm @@ -3,46 +3,46 @@ Serial:: push bc push de push hl - ld a, [hSerialConnectionStatus] + ldh a, [hSerialConnectionStatus] inc a jr z, .connectionNotYetEstablished - ld a, [rSB] - ld [hSerialReceiveData], a - ld a, [hSerialSendData] - ld [rSB], a - ld a, [hSerialConnectionStatus] + ldh a, [rSB] + ldh [hSerialReceiveData], a + ldh a, [hSerialSendData] + ldh [rSB], a + ldh a, [hSerialConnectionStatus] cp USING_INTERNAL_CLOCK jr z, .done ; using external clock ld a, START_TRANSFER_EXTERNAL_CLOCK - ld [rSC], a + ldh [rSC], a jr .done .connectionNotYetEstablished - ld a, [rSB] - ld [hSerialReceiveData], a - ld [hSerialConnectionStatus], a + ldh a, [rSB] + ldh [hSerialReceiveData], a + ldh [hSerialConnectionStatus], a cp USING_INTERNAL_CLOCK jr z, .usingInternalClock ; using external clock xor a - ld [rSB], a + ldh [rSB], a ld a, $3 - ld [rDIV], a + ldh [rDIV], a .waitLoop - ld a, [rDIV] + ldh a, [rDIV] bit 7, a jr nz, .waitLoop ld a, START_TRANSFER_EXTERNAL_CLOCK - ld [rSC], a + ldh [rSC], a jr .done .usingInternalClock xor a - ld [rSB], a + ldh [rSB], a .done ld a, $1 - ld [hSerialReceivedNewData], a + ldh [hSerialReceivedNewData], a ld a, SERIAL_NO_DATA_BYTE - ld [hSerialSendData], a + ldh [hSerialSendData], a pop hl pop de pop bc @@ -54,10 +54,10 @@ Serial:: ; bc = length of data Serial_ExchangeBytes:: ld a, 1 - ld [hSerialIgnoringInitialData], a + ldh [hSerialIgnoringInitialData], a .loop ld a, [hl] - ld [hSerialSendData], a + ldh [hSerialSendData], a call Serial_ExchangeByte push bc ld b, a @@ -66,7 +66,7 @@ Serial_ExchangeBytes:: .waitLoop dec a jr nz, .waitLoop - ld a, [hSerialIgnoringInitialData] + ldh a, [hSerialIgnoringInitialData] and a ld a, b pop bc @@ -75,7 +75,7 @@ Serial_ExchangeBytes:: cp SERIAL_PREAMBLE_BYTE jr nz, .loop xor a - ld [hSerialIgnoringInitialData], a + ldh [hSerialIgnoringInitialData], a jr .loop .storeReceivedByte ld [de], a @@ -88,17 +88,17 @@ Serial_ExchangeBytes:: Serial_ExchangeByte:: xor a - ld [hSerialReceivedNewData], a - ld a, [hSerialConnectionStatus] + ldh [hSerialReceivedNewData], a + ldh a, [hSerialConnectionStatus] cp USING_INTERNAL_CLOCK jr nz, .loop ld a, START_TRANSFER_INTERNAL_CLOCK - ld [rSC], a + ldh [rSC], a .loop - ld a, [hSerialReceivedNewData] + ldh a, [hSerialReceivedNewData] and a jr nz, .ok - ld a, [hSerialConnectionStatus] + ldh a, [hSerialConnectionStatus] cp USING_EXTERNAL_CLOCK jr nz, .doNotIncrementUnknownCounter call IsUnknownCounterZero @@ -116,7 +116,7 @@ Serial_ExchangeByte:: jr nz, .loop jp SetUnknownCounterToFFFF .doNotIncrementUnknownCounter - ld a, [rIE] + ldh a, [rIE] and (1 << SERIAL) | (1 << TIMER) | (1 << LCD_STAT) | (1 << VBLANK) cp (1 << SERIAL) jr nz, .loop @@ -128,7 +128,7 @@ Serial_ExchangeByte:: dec a ld [wUnknownSerialCounter2 + 1], a jr nz, .loop - ld a, [hSerialConnectionStatus] + ldh a, [hSerialConnectionStatus] cp USING_EXTERNAL_CLOCK jr z, .ok ld a, 255 @@ -137,8 +137,8 @@ Serial_ExchangeByte:: jr nz, .waitLoop .ok xor a - ld [hSerialReceivedNewData], a - ld a, [rIE] + ldh [hSerialReceivedNewData], a + ldh a, [rIE] and (1 << SERIAL) | (1 << TIMER) | (1 << LCD_STAT) | (1 << VBLANK) sub (1 << SERIAL) jr nz, .skipReloadingUnknownCounter2 @@ -146,7 +146,7 @@ Serial_ExchangeByte:: ld a, $50 ld [wUnknownSerialCounter2 + 1], a .skipReloadingUnknownCounter2 - ld a, [hSerialReceiveData] + ldh a, [hSerialReceiveData] cp SERIAL_NO_DATA_BYTE ret nz call IsUnknownCounterZero @@ -164,13 +164,13 @@ Serial_ExchangeByte:: call IsUnknownCounterZero jr z, SetUnknownCounterToFFFF .done - ld a, [rIE] + ldh a, [rIE] and (1 << SERIAL) | (1 << TIMER) | (1 << LCD_STAT) | (1 << VBLANK) cp (1 << SERIAL) ld a, SERIAL_NO_DATA_BYTE ret z ld a, [hl] - ld [hSerialSendData], a + ldh [hSerialSendData], a call DelayFrame jp Serial_ExchangeByte @@ -203,18 +203,18 @@ Serial_ExchangeLinkMenuSelection:: ld de, wLinkMenuSelectionReceiveBuffer ld c, 2 ; number of bytes to save ld a, 1 - ld [hSerialIgnoringInitialData], a + ldh [hSerialIgnoringInitialData], a .loop call DelayFrame ld a, [hl] - ld [hSerialSendData], a + ldh [hSerialSendData], a call Serial_ExchangeByte ld b, a inc hl - ld a, [hSerialIgnoringInitialData] + ldh a, [hSerialIgnoringInitialData] and a ld a, 0 - ld [hSerialIgnoringInitialData], a + ldh [hSerialIgnoringInitialData], a jr nz, .loop ld a, b ld [de], a @@ -225,7 +225,7 @@ Serial_ExchangeLinkMenuSelection:: Serial_PrintWaitingTextAndSyncAndExchangeNybble:: call SaveScreenTilesToBuffer1 - callab PrintWaitingText + callfar PrintWaitingText call Serial_SyncAndExchangeNybble jp LoadScreenTilesFromBuffer1 @@ -273,20 +273,20 @@ Serial_ExchangeNybble:: call .doExchange ld a, [wSerialExchangeNybbleSendData] add $60 - ld [hSerialSendData], a - ld a, [hSerialConnectionStatus] + ldh [hSerialSendData], a + ldh a, [hSerialConnectionStatus] cp USING_INTERNAL_CLOCK jr nz, .doExchange ld a, START_TRANSFER_INTERNAL_CLOCK - ld [rSC], a + ldh [rSC], a .doExchange - ld a, [hSerialReceiveData] + ldh a, [hSerialReceiveData] ld [wSerialExchangeNybbleTempReceiveData], a and $f0 cp $60 ret nz xor a - ld [hSerialReceiveData], a + ldh [hSerialReceiveData], a ld a, [wSerialExchangeNybbleTempReceiveData] and $f ld [wSerialExchangeNybbleReceiveData], a @@ -294,19 +294,19 @@ Serial_ExchangeNybble:: Serial_SendZeroByte:: xor a - ld [hSerialSendData], a - ld a, [hSerialConnectionStatus] + ldh [hSerialSendData], a + ldh a, [hSerialConnectionStatus] cp USING_INTERNAL_CLOCK ret nz ld a, START_TRANSFER_INTERNAL_CLOCK - ld [rSC], a + ldh [rSC], a ret Serial_TryEstablishingExternallyClockedConnection:: ld a, ESTABLISH_CONNECTION_WITH_EXTERNAL_CLOCK - ld [rSB], a + ldh [rSB], a xor a - ld [hSerialReceiveData], a + ldh [hSerialReceiveData], a ld a, START_TRANSFER_EXTERNAL_CLOCK - ld [rSC], a + ldh [rSC], a ret diff --git a/home/start_menu.asm b/home/start_menu.asm index 38333644..5b29f67a 100755 --- a/home/start_menu.asm +++ b/home/start_menu.asm @@ -1,6 +1,6 @@ DisplayStartMenu:: ld a, BANK(StartMenu_Pokedex) - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a ld a, [wWalkBikeSurfState] ; walking/biking/surfing ld [wWalkBikeSurfStateCopy], a @@ -8,8 +8,8 @@ DisplayStartMenu:: call PlaySound RedisplayStartMenu:: - callba DrawStartMenu - callba PrintSafariZoneSteps ; print Safari Zone info, if in Safari Zone + farcall DrawStartMenu + farcall PrintSafariZoneSteps ; print Safari Zone info, if in Safari Zone call UpdateSprites .loop call HandleMenuInput @@ -78,7 +78,7 @@ RedisplayStartMenu:: ; EXIT falls through to here CloseStartMenu:: call Joypad - ld a, [hJoyPressed] + ldh a, [hJoyPressed] bit 0, a ; was A button newly pressed? jr nz, CloseStartMenu call LoadTextBoxTilePatterns diff --git a/home/text.asm b/home/text.asm index 2047eaaa..bdd871cb 100644 --- a/home/text.asm +++ b/home/text.asm @@ -62,7 +62,7 @@ PlaceNextChar:: cp "<NEXT>" jr nz, .NotNext ld bc, 2 * SCREEN_WIDTH - ld a, [hFlagsFFF6] + ldh a, [hFlagsFFF6] bit 2, a jr z, .ok ld bc, SCREEN_WIDTH @@ -76,7 +76,7 @@ PlaceNextChar:: cp "<LINE>" jr nz, .NotLine pop hl - coord hl, 1, 16 + hlcoord 1, 16 push hl jp NextChar @@ -141,12 +141,12 @@ SixDotsChar:: print_name SixDotsCharText PlacePKMN:: print_name PlacePKMNText PlaceMoveTargetsName:: - ld a, [hWhoseTurn] + ldh a, [hWhoseTurn] xor 1 jr PlaceMoveUsersName.place PlaceMoveUsersName:: - ld a, [hWhoseTurn] + ldh a, [hWhoseTurn] .place: push de @@ -207,12 +207,12 @@ PromptText:: cp LINK_STATE_BATTLING jp z, .ok ld a, "▼" - Coorda 18, 16 + ldcoord_a 18, 16 .ok call ProtectedDelay3 call ManualTextScroll ld a, " " - Coorda 18, 16 + ldcoord_a 18, 16 DoneText:: pop hl @@ -226,49 +226,49 @@ DoneText:: Paragraph:: push de ld a, "▼" - Coorda 18, 16 + ldcoord_a 18, 16 call ProtectedDelay3 call ManualTextScroll - coord hl, 1, 13 + hlcoord 1, 13 lb bc, 4, 18 call ClearScreenArea ld c, 20 call DelayFrames pop de - coord hl, 1, 14 + hlcoord 1, 14 jp NextChar PageChar:: push de ld a, "▼" - Coorda 18, 16 + ldcoord_a 18, 16 call ProtectedDelay3 call ManualTextScroll - coord hl, 1, 10 + hlcoord 1, 10 lb bc, 7, 18 call ClearScreenArea ld c, 20 call DelayFrames pop de pop hl - coord hl, 1, 11 + hlcoord 1, 11 push hl jp NextChar _ContText:: ld a, "▼" - Coorda 18, 16 + ldcoord_a 18, 16 call ProtectedDelay3 push de call ManualTextScroll pop de ld a, " " - Coorda 18, 16 + ldcoord_a 18, 16 _ContTextNoPause:: push de call ScrollTextUpOneLine call ScrollTextUpOneLine - coord hl, 1, 16 + hlcoord 1, 16 pop de jp NextChar @@ -277,8 +277,8 @@ _ContTextNoPause:: ; first time, copy the two rows of text to the "in between" rows that are usually emtpy ; second time, copy the bottom row of text into the top row of text ScrollTextUpOneLine:: - coord hl, 0, 14 ; top row of text - coord de, 0, 13 ; empty line above text + hlcoord 0, 14 ; top row of text + decoord 0, 13 ; empty line above text ld b, SCREEN_WIDTH * 3 .copyText ld a, [hli] @@ -286,7 +286,7 @@ ScrollTextUpOneLine:: inc de dec b jr nz, .copyText - coord hl, 1, 16 + hlcoord 1, 16 ld a, " " ld b, SCREEN_WIDTH - 2 .clearText @@ -313,7 +313,7 @@ TextCommandProcessor:: push af set 1, a ld e, a - ld a, [hClearLetterPrintingDelayFlags] + ldh a, [hClearLetterPrintingDelayFlags] xor e ld [wLetterPrintingDelayFlags], a ld a, c @@ -424,7 +424,7 @@ TextCommand_MOVE:: TextCommand_LOW:: ; write text at (1,16) pop hl - coord bc, 1, 16 ; second line of dialogue text box + bccoord 1, 16 ; second line of dialogue text box jp NextTextCommand TextCommand_PROMPT_BUTTON:: @@ -433,12 +433,12 @@ TextCommand_PROMPT_BUTTON:: cp LINK_STATE_BATTLING jp z, TextCommand_WAIT_BUTTON ld a, "▼" - Coorda 18, 16 ; place down arrow in lower right corner of dialogue text box + ldcoord_a 18, 16 ; place down arrow in lower right corner of dialogue text box push bc call ManualTextScroll ; blink arrow and wait for A or B to be pressed pop bc ld a, " " - Coorda 18, 16 ; overwrite down arrow with blank space + ldcoord_a 18, 16 ; overwrite down arrow with blank space pop hl jp NextTextCommand @@ -446,11 +446,11 @@ TextCommand_SCROLL:: ; pushes text up two lines and sets the BC cursor to the border tile ; below the first character column of the text box. ld a, " " - Coorda 18, 16 ; place blank space in lower right corner of dialogue text box + ldcoord_a 18, 16 ; place blank space in lower right corner of dialogue text box call ScrollTextUpOneLine call ScrollTextUpOneLine pop hl - coord bc, 1, 16 ; second line of dialogue text box + bccoord 1, 16 ; second line of dialogue text box jp NextTextCommand TextCommand_START_ASM:: @@ -489,7 +489,7 @@ TextCommand_PAUSE:: ; wait for button press or 30 frames push bc call Joypad - ld a, [hJoyHeld] + ldh a, [hJoyHeld] and A_BUTTON | B_BUTTON jr nz, .done ld c, 30 ; half a second @@ -565,7 +565,7 @@ TextCommand_DOTS:: push de call Joypad pop de - ld a, [hJoyHeld] ; joypad state + ldh a, [hJoyHeld] ; joypad state and A_BUTTON | B_BUTTON jr nz, .next ; if so, skip the delay ld c, 10 @@ -590,7 +590,7 @@ TextCommand_WAIT_BUTTON:: TextCommand_FAR:: ; write text from a different bank (little endian) pop hl - ld a, [hLoadedROMBank] + ldh a, [hLoadedROMBank] push af ld a, [hli] @@ -599,7 +599,7 @@ TextCommand_FAR:: ld d, a ld a, [hli] - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a push hl @@ -609,7 +609,7 @@ TextCommand_FAR:: pop hl pop af - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a jp NextTextCommand diff --git a/home/text_script.asm b/home/text_script.asm index 2dd2dbde..b9c3c8e4 100644 --- a/home/text_script.asm +++ b/home/text_script.asm @@ -1,9 +1,9 @@ ; this function is used to display sign messages, sprite dialog, etc. ; INPUT: [hSpriteIndexOrTextID] = sprite ID or text ID DisplayTextID:: - ld a, [hLoadedROMBank] + ldh a, [hLoadedROMBank] push af - callba DisplayTextIDInit ; initialization + farcall DisplayTextIDInit ; initialization ld hl, wTextPredefFlag bit 0, [hl] res 0, [hl] @@ -12,13 +12,13 @@ DisplayTextID:: call SwitchToMapRomBank .skipSwitchToMapBank ld a, 30 ; half a second - ld [hFrameCounter], a ; used as joypad poll timer + ldh [hFrameCounter], 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 + ldh a, [hSpriteIndexOrTextID] ; text ID ld [wSpriteIndex], a dict TEXT_START_MENU, DisplayStartMenu @@ -29,7 +29,7 @@ DisplayTextID:: ld a, [wNumSprites] ld e, a - ld a, [hSpriteIndexOrTextID] ; sprite ID + ldh a, [hSpriteIndexOrTextID] ; sprite ID cp e jr z, .spriteHandling jr nc, .skipSpriteHandling @@ -38,11 +38,11 @@ DisplayTextID:: push hl push de push bc - callba UpdateSpriteFacingOffsetAndDelayMovement ; update the graphics of the sprite the player is talking to (to face the right direction) + farcall UpdateSpriteFacingOffsetAndDelayMovement ; update the graphics of the sprite the player is talking to (to face the right direction) pop bc pop de ld hl, wMapSpriteData ; NPC text entries - ld a, [hSpriteIndexOrTextID] + ldh a, [hSpriteIndexOrTextID] dec a add a add l @@ -79,9 +79,9 @@ ENDM dict TX_SCRIPT_PLAYERS_PC, TextScript_ItemStoragePC dict TX_SCRIPT_BILLS_PC, TextScript_BillsPC dict TX_SCRIPT_POKECENTER_PC, TextScript_PokemonCenterPC - dict2 TX_SCRIPT_VENDING_MACHINE, callba VendingMachineMenu + dict2 TX_SCRIPT_VENDING_MACHINE, farcall VendingMachineMenu dict TX_SCRIPT_PRIZE_VENDOR, TextScript_GameCornerPrizeMenu - dict2 TX_SCRIPT_CABLE_CLUB_RECEPTIONIST, callab CableClubNPC + dict2 TX_SCRIPT_CABLE_CLUB_RECEPTIONIST, callfar CableClubNPC call PrintText_NoCreatingTextBox ; display the text ld a, [wDoNotWaitForButtonPressAfterDisplayingText] @@ -97,7 +97,7 @@ AfterDisplayingTextID:: ; loop to hold the dialogue box open as long as the player keeps holding down the A button HoldTextDisplayOpen:: call Joypad - ld a, [hJoyHeld] + ldh a, [hJoyHeld] bit 0, a ; is the A button being pressed? jr nz, HoldTextDisplayOpen @@ -105,25 +105,25 @@ CloseTextDisplay:: ld a, [wCurMap] call SwitchToMapRomBank ld a, $90 - ld [hWY], a ; move the window off the screen + ldh [hWY], a ; move the window off the screen call DelayFrame call LoadGBPal xor a - ld [hAutoBGTransferEnabled], a ; disable continuous WRAM to VRAM transfer each V-blank + ldh [hAutoBGTransferEnabled], 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, wSprite01StateData2 + 9 ; should be wSprite01StateData1FacingDirection? + ld hl, wSprite01StateData2OrigFacingDirection ld c, $0f ld de, $10 .restoreSpriteFacingDirectionLoop - ld a, [hl] + ld a, [hl] ; x#SPRITESTATEDATA2_ORIGFACINGDIRECTION dec h - ld [hl], a + ld [hl], a ; [x#SPRITESTATEDATA1_FACINGDIRECTION] inc h add hl, de dec c jr nz, .restoreSpriteFacingDirectionLoop ld a, BANK(InitMapSprites) - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a call InitMapSprites ; reload sprite tile pattern data (since it was partially overwritten by text tile patterns) ld hl, wFontLoaded @@ -133,7 +133,7 @@ CloseTextDisplay:: call z, LoadPlayerSpriteGraphics call LoadCurrentMapView pop af - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a jp UpdateSprites @@ -146,14 +146,14 @@ DisplayPokemartDialogue:: call LoadItemList ld a, PRICEDITEMLISTMENU ld [wListMenuID], a - ld a, [hLoadedROMBank] + ldh a, [hLoadedROMBank] push af ld a, BANK(DisplayPokemartDialogue_) - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a call DisplayPokemartDialogue_ pop af - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a jp AfterDisplayingTextID @@ -180,24 +180,24 @@ LoadItemList:: DisplayPokemonCenterDialogue:: ; zeroing these doesn't appear to serve any purpose xor a - ld [hItemPrice], a - ld [hItemPrice + 1], a - ld [hItemPrice + 2], a + ldh [hItemPrice], a + ldh [hItemPrice + 1], a + ldh [hItemPrice + 2], a inc hl - ld a, [hLoadedROMBank] + ldh a, [hLoadedROMBank] push af ld a, BANK(DisplayPokemonCenterDialogue_) - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a call DisplayPokemonCenterDialogue_ pop af - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a jp AfterDisplayingTextID DisplaySafariGameOverText:: - callab PrintSafariGameOverText + callfar PrintSafariGameOverText jp AfterDisplayingTextID DisplayPokemonFaintedText:: diff --git a/home/textbox.asm b/home/textbox.asm new file mode 100644 index 00000000..5067b044 --- /dev/null +++ b/home/textbox.asm @@ -0,0 +1,16 @@ +; function to draw various text boxes +; INPUT: +; [wTextBoxID] = text box ID +; b, c = y, x cursor position (TWO_OPTION_MENU only) +DisplayTextBoxID:: + ldh a, [hLoadedROMBank] + push af + ld a, BANK(DisplayTextBoxID_) + ldh [hLoadedROMBank], a + ld [MBC1RomBank], a + call DisplayTextBoxID_ + pop bc + ld a, b + ldh [hLoadedROMBank], a + ld [MBC1RomBank], a + ret diff --git a/home/tilemap.asm b/home/tilemap.asm new file mode 100644 index 00000000..afee7097 --- /dev/null +++ b/home/tilemap.asm @@ -0,0 +1,61 @@ +FillMemory:: +; Fill bc bytes at hl with a. + push de + ld d, a +.loop + ld a, d + ld [hli], a + dec bc + ld a, b + or c + jr nz, .loop + pop de + ret + +UncompressSpriteFromDE:: +; Decompress pic at a:de. + ld hl, wSpriteInputPtr + ld [hl], e + inc hl + ld [hl], d + jp UncompressSpriteData + +SaveScreenTilesToBuffer2:: + hlcoord 0, 0 + ld de, wTileMapBackup2 + ld bc, SCREEN_WIDTH * SCREEN_HEIGHT + call CopyData + ret + +LoadScreenTilesFromBuffer2:: + call LoadScreenTilesFromBuffer2DisableBGTransfer + ld a, 1 + ldh [hAutoBGTransferEnabled], a + ret + +; loads screen tiles stored in wTileMapBackup2 but leaves hAutoBGTransferEnabled disabled +LoadScreenTilesFromBuffer2DisableBGTransfer:: + xor a + ldh [hAutoBGTransferEnabled], a + ld hl, wTileMapBackup2 + decoord 0, 0 + ld bc, SCREEN_WIDTH * SCREEN_HEIGHT + call CopyData + ret + +SaveScreenTilesToBuffer1:: + hlcoord 0, 0 + ld de, wTileMapBackup + ld bc, SCREEN_WIDTH * SCREEN_HEIGHT + jp CopyData + +LoadScreenTilesFromBuffer1:: + xor a + ldh [hAutoBGTransferEnabled], a + ld hl, wTileMapBackup + decoord 0, 0 + ld bc, SCREEN_WIDTH * SCREEN_HEIGHT + call CopyData + ld a, 1 + ldh [hAutoBGTransferEnabled], a + ret diff --git a/home/trainers.asm b/home/trainers.asm index 22601db8..039c4ec8 100644 --- a/home/trainers.asm +++ b/home/trainers.asm @@ -144,7 +144,7 @@ CheckFightingMapTrainers:: ld a, D_RIGHT | D_LEFT | D_UP | D_DOWN ld [wJoyIgnore], a xor a - ld [hJoyHeld], a + ldh [hJoyHeld], a call TrainerWalkUpToPlayer_Bank0 ld hl, wCurMapScript inc [hl] ; increment map script index (next script function is usually DisplayEnemyTrainerTextAndStartBattle) @@ -157,7 +157,7 @@ DisplayEnemyTrainerTextAndStartBattle:: 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 + ldh [hSpriteIndexOrTextID], a call DisplayTextID ; fall through @@ -211,15 +211,15 @@ EndTrainerBattle:: ResetButtonPressedAndMapScript:: xor a ld [wJoyIgnore], a - ld [hJoyHeld], a - ld [hJoyPressed], a - ld [hJoyReleased], a + ldh [hJoyHeld], a + ldh [hJoyPressed], a + ldh [hJoyReleased], a ld [wCurMapScript], a ; reset battle status ret ; calls TrainerWalkUpToPlayer TrainerWalkUpToPlayer_Bank0:: - jpba TrainerWalkUpToPlayer + farjp TrainerWalkUpToPlayer ; sets opponent type and mon set/lvl based on the engaging trainer data InitBattleEnemyParameters:: @@ -302,7 +302,7 @@ CheckForEngagingTrainers:: ; hl = text if the player wins ; de = text if the player loses SaveEndBattleTextPointers:: - ld a, [hLoadedROMBank] + ldh a, [hLoadedROMBank] ld [wEndBattleTextRomBank], a ld a, h ld [wEndBattleWinTextPointer], a @@ -337,20 +337,20 @@ PrintEndBattleText:: res 7, [hl] pop hl ret z - ld a, [hLoadedROMBank] + ldh a, [hLoadedROMBank] push af ld a, [wEndBattleTextRomBank] - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a push hl - callba SaveTrainerName + farcall SaveTrainerName ld hl, TrainerEndBattleText call PrintText pop hl pop af - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a - callba FreezeEnemyTrainerSprite + farcall FreezeEnemyTrainerSprite jp WaitForSoundToFinish GetSavedEndBattleTextPointer:: diff --git a/home/trainers2.asm b/home/trainers2.asm new file mode 100644 index 00000000..950eabb2 --- /dev/null +++ b/home/trainers2.asm @@ -0,0 +1,35 @@ +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 + jp BankswitchBack +.linkBattle + ld hl, wTrainerPicPointer + ld de, RedPicFront + ld [hl], e + inc hl + ld [hl], d + ret + +GetTrainerName:: + farjp GetTrainerName_ diff --git a/home/uncompress.asm b/home/uncompress.asm index cfc39f0f..9d08aa60 100644 --- a/home/uncompress.asm +++ b/home/uncompress.asm @@ -2,10 +2,10 @@ ; bank is given in a, sprite input stream is pointed to in wSpriteInputPtr UncompressSpriteData:: ld b, a - ld a, [hLoadedROMBank] + ldh a, [hLoadedROMBank] push af ld a, b - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a ld a, SRAM_ENABLE ld [MBC1SRamEnable], a @@ -13,15 +13,15 @@ UncompressSpriteData:: ld [MBC1SRamBank], a call _UncompressSpriteData pop af - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a ret ; initializes necessary data to load a sprite and runs UncompressSpriteDataLoop _UncompressSpriteData:: ld hl, sSpriteBuffer1 - ld c, (2*SPRITEBUFFERSIZE) % $100 - ld b, (2*SPRITEBUFFERSIZE) / $100 + ld c, LOW(2 * SPRITEBUFFERSIZE) + ld b, HIGH(2 * SPRITEBUFFERSIZE) xor a call FillMemory ; clear sprite buffer 1 and 2 ld a, $1 diff --git a/home/update_sprites.asm b/home/update_sprites.asm new file mode 100644 index 00000000..80ea14d3 --- /dev/null +++ b/home/update_sprites.asm @@ -0,0 +1,14 @@ +UpdateSprites:: + ld a, [wUpdateSpritesEnabled] + dec a + ret nz + ldh a, [hLoadedROMBank] + push af + ld a, BANK(_UpdateSprites) + ldh [hLoadedROMBank], a + ld [MBC1RomBank], a + call _UpdateSprites + pop af + ldh [hLoadedROMBank], a + ld [MBC1RomBank], a + ret diff --git a/home/vblank.asm b/home/vblank.asm index 78f5f69d..4c7abc20 100644 --- a/home/vblank.asm +++ b/home/vblank.asm @@ -5,19 +5,19 @@ VBlank:: push de push hl - ld a, [hLoadedROMBank] + ldh a, [hLoadedROMBank] ld [wVBlankSavedROMBank], a - ld a, [hSCX] - ld [rSCX], a - ld a, [hSCY] - ld [rSCY], a + ldh a, [hSCX] + ldh [rSCX], a + ldh a, [hSCY] + ldh [rSCY], a ld a, [wDisableVBlankWYUpdate] and a jr nz, .ok - ld a, [hWY] - ld [rWY], a + ldh a, [hWY] + ldh [rWY], a .ok call AutoBgMapTransfer @@ -28,7 +28,7 @@ VBlank:: call UpdateMovingBgTiles call hDMARoutine ld a, BANK(PrepareOAMData) - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a call PrepareOAMData @@ -36,24 +36,24 @@ VBlank:: call Random - ld a, [hVBlankOccurred] + ldh a, [hVBlankOccurred] and a jr z, .skipZeroing xor a - ld [hVBlankOccurred], a + ldh [hVBlankOccurred], a .skipZeroing - ld a, [hFrameCounter] + ldh a, [hFrameCounter] and a jr z, .skipDec dec a - ld [hFrameCounter], a + ldh [hFrameCounter], a .skipDec call FadeOutAudio ld a, [wAudioROMBank] ; music ROM bank - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a cp BANK(Audio1_UpdateMusic) @@ -72,14 +72,14 @@ VBlank:: call Audio3_UpdateMusic .afterMusic - callba TrackPlayTime ; keep track of time played + farcall TrackPlayTime ; keep track of time played - ld a, [hDisableJoypadPolling] + ldh a, [hDisableJoypadPolling] and a call z, ReadJoypad ld a, [wVBlankSavedROMBank] - ld [hLoadedROMBank], a + ldh [hLoadedROMBank], a ld [MBC1RomBank], a pop hl @@ -96,10 +96,10 @@ DelayFrame:: NOT_VBLANKED EQU 1 ld a, NOT_VBLANKED - ld [hVBlankOccurred], a + ldh [hVBlankOccurred], a .halt halt - ld a, [hVBlankOccurred] + ldh a, [hVBlankOccurred] and a jr nz, .halt ret diff --git a/home/vcopy.asm b/home/vcopy.asm index e2325d5c..458fa610 100644 --- a/home/vcopy.asm +++ b/home/vcopy.asm @@ -40,19 +40,19 @@ ClearBgMap:: ; However, this function is also called repeatedly to redraw the whole screen ; when necessary. It is also used in trade animation and elevator code. RedrawRowOrColumn:: - ld a, [hRedrawRowOrColumnMode] + ldh a, [hRedrawRowOrColumnMode] and a ret z ld b, a xor a - ld [hRedrawRowOrColumnMode], a + ldh [hRedrawRowOrColumnMode], a dec b jr nz, .redrawRow .redrawColumn ld hl, wRedrawRowOrColumnSrcTiles - ld a, [hRedrawRowOrColumnDest] + ldh a, [hRedrawRowOrColumnDest] ld e, a - ld a, [hRedrawRowOrColumnDest + 1] + ldh a, [hRedrawRowOrColumnDest + 1] ld d, a ld c, SCREEN_HEIGHT .loop1 @@ -75,13 +75,13 @@ RedrawRowOrColumn:: dec c jr nz, .loop1 xor a - ld [hRedrawRowOrColumnMode], a + ldh [hRedrawRowOrColumnMode], a ret .redrawRow ld hl, wRedrawRowOrColumnSrcTiles - ld a, [hRedrawRowOrColumnDest] + ldh a, [hRedrawRowOrColumnDest] ld e, a - ld a, [hRedrawRowOrColumnDest + 1] + ldh a, [hRedrawRowOrColumnDest + 1] ld d, a push de call .DrawHalf ; draw upper half @@ -120,51 +120,51 @@ RedrawRowOrColumn:: ; the above function, RedrawRowOrColumn, is used when walking to ; improve efficiency. AutoBgMapTransfer:: - ld a, [hAutoBGTransferEnabled] + ldh a, [hAutoBGTransferEnabled] and a ret z ld hl, sp + 0 ld a, h - ld [hSPTemp], a + ldh [hSPTemp], a ld a, l - ld [hSPTemp + 1], a ; save stack pinter - ld a, [hAutoBGTransferPortion] + ldh [hSPTemp + 1], a ; save stack pinter + ldh a, [hAutoBGTransferPortion] and a jr z, .transferTopThird dec a jr z, .transferMiddleThird .transferBottomThird - coord hl, 0, 12 + hlcoord 0, 12 ld sp, hl - ld a, [hAutoBGTransferDest + 1] + ldh a, [hAutoBGTransferDest + 1] ld h, a - ld a, [hAutoBGTransferDest] + ldh a, [hAutoBGTransferDest] ld l, a ld de, (12 * 32) add hl, de xor a ; TRANSFERTOP jr .doTransfer .transferTopThird - coord hl, 0, 0 + hlcoord 0, 0 ld sp, hl - ld a, [hAutoBGTransferDest + 1] + ldh a, [hAutoBGTransferDest + 1] ld h, a - ld a, [hAutoBGTransferDest] + ldh a, [hAutoBGTransferDest] ld l, a ld a, TRANSFERMIDDLE jr .doTransfer .transferMiddleThird - coord hl, 0, 6 + hlcoord 0, 6 ld sp, hl - ld a, [hAutoBGTransferDest + 1] + ldh a, [hAutoBGTransferDest + 1] ld h, a - ld a, [hAutoBGTransferDest] + ldh a, [hAutoBGTransferDest] ld l, a ld de, (6 * 32) add hl, de ld a, TRANSFERBOTTOM .doTransfer - ld [hAutoBGTransferPortion], a ; store next portion + ldh [hAutoBGTransferPortion], a ; store next portion ld b, 6 TransferBgRows:: @@ -192,9 +192,9 @@ TransferBgRows:: dec b jr nz, TransferBgRows - ld a, [hSPTemp] + ldh a, [hSPTemp] ld h, a - ld a, [hSPTemp + 1] + ldh a, [hSPTemp + 1] ld l, a ld sp, hl ret @@ -202,27 +202,27 @@ TransferBgRows:: ; Copies [hVBlankCopyBGNumRows] rows from hVBlankCopyBGSource to hVBlankCopyBGDest. ; If hVBlankCopyBGSource is XX00, the transfer is disabled. VBlankCopyBgMap:: - ld a, [hVBlankCopyBGSource] ; doubles as enabling byte + ldh a, [hVBlankCopyBGSource] ; doubles as enabling byte and a ret z ld hl, sp + 0 ld a, h - ld [hSPTemp], a + ldh [hSPTemp], a ld a, l - ld [hSPTemp + 1], a ; save stack pointer - ld a, [hVBlankCopyBGSource] + ldh [hSPTemp + 1], a ; save stack pointer + ldh a, [hVBlankCopyBGSource] ld l, a - ld a, [hVBlankCopyBGSource + 1] + ldh a, [hVBlankCopyBGSource + 1] ld h, a ld sp, hl - ld a, [hVBlankCopyBGDest] + ldh a, [hVBlankCopyBGDest] ld l, a - ld a, [hVBlankCopyBGDest + 1] + ldh a, [hVBlankCopyBGDest + 1] ld h, a - ld a, [hVBlankCopyBGNumRows] + ldh a, [hVBlankCopyBGNumRows] ld b, a xor a - ld [hVBlankCopyBGSource], a ; disable transfer so it doesn't continue next V-blank + ldh [hVBlankCopyBGSource], a ; disable transfer so it doesn't continue next V-blank jr TransferBgRows @@ -234,31 +234,31 @@ VBlankCopyDouble:: ; The process is straightforward: ; copy each byte twice. - ld a, [hVBlankCopyDoubleSize] + ldh a, [hVBlankCopyDoubleSize] and a ret z ld hl, sp + 0 ld a, h - ld [hSPTemp], a + ldh [hSPTemp], a ld a, l - ld [hSPTemp + 1], a + ldh [hSPTemp + 1], a - ld a, [hVBlankCopyDoubleSource] + ldh a, [hVBlankCopyDoubleSource] ld l, a - ld a, [hVBlankCopyDoubleSource + 1] + ldh a, [hVBlankCopyDoubleSource + 1] ld h, a ld sp, hl - ld a, [hVBlankCopyDoubleDest] + ldh a, [hVBlankCopyDoubleDest] ld l, a - ld a, [hVBlankCopyDoubleDest + 1] + ldh a, [hVBlankCopyDoubleDest + 1] ld h, a - ld a, [hVBlankCopyDoubleSize] + ldh a, [hVBlankCopyDoubleSize] ld b, a xor a ; transferred - ld [hVBlankCopyDoubleSize], a + ldh [hVBlankCopyDoubleSize], a .loop REPT 3 @@ -286,19 +286,19 @@ VBlankCopyDouble:: jr nz, .loop ld a, l - ld [hVBlankCopyDoubleDest], a + ldh [hVBlankCopyDoubleDest], a ld a, h - ld [hVBlankCopyDoubleDest + 1], a + ldh [hVBlankCopyDoubleDest + 1], a ld hl, sp + 0 ld a, l - ld [hVBlankCopyDoubleSource], a + ldh [hVBlankCopyDoubleSource], a ld a, h - ld [hVBlankCopyDoubleSource + 1], a + ldh [hVBlankCopyDoubleSource + 1], a - ld a, [hSPTemp] + ldh a, [hSPTemp] ld h, a - ld a, [hSPTemp + 1] + ldh a, [hSPTemp + 1] ld l, a ld sp, hl @@ -312,31 +312,31 @@ VBlankCopy:: ; Source and destination addresses are updated, ; so transfer can continue in subsequent calls. - ld a, [hVBlankCopySize] + ldh a, [hVBlankCopySize] and a ret z ld hl, sp + 0 ld a, h - ld [hSPTemp], a + ldh [hSPTemp], a ld a, l - ld [hSPTemp + 1], a + ldh [hSPTemp + 1], a - ld a, [hVBlankCopySource] + ldh a, [hVBlankCopySource] ld l, a - ld a, [hVBlankCopySource + 1] + ldh a, [hVBlankCopySource + 1] ld h, a ld sp, hl - ld a, [hVBlankCopyDest] + ldh a, [hVBlankCopyDest] ld l, a - ld a, [hVBlankCopyDest + 1] + ldh a, [hVBlankCopyDest + 1] ld h, a - ld a, [hVBlankCopySize] + ldh a, [hVBlankCopySize] ld b, a xor a ; transferred - ld [hVBlankCopySize], a + ldh [hVBlankCopySize], a .loop REPT 7 @@ -356,19 +356,19 @@ VBlankCopy:: jr nz, .loop ld a, l - ld [hVBlankCopyDest], a + ldh [hVBlankCopyDest], a ld a, h - ld [hVBlankCopyDest + 1], a + ldh [hVBlankCopyDest + 1], a ld hl, sp + 0 ld a, l - ld [hVBlankCopySource], a + ldh [hVBlankCopySource], a ld a, h - ld [hVBlankCopySource + 1], a + ldh [hVBlankCopySource + 1], a - ld a, [hSPTemp] + ldh a, [hSPTemp] ld h, a - ld a, [hSPTemp + 1] + ldh a, [hSPTemp + 1] ld l, a ld sp, hl @@ -379,13 +379,13 @@ UpdateMovingBgTiles:: ; Animate water and flower ; tiles in the overworld. - ld a, [hTilesetType] + ldh a, [hTilesetType] and a ret z ; no animations if indoors (or if a menu set this to 0) - ld a, [hMovingBGTilesCounter1] + ldh a, [hMovingBGTilesCounter1] inc a - ld [hMovingBGTilesCounter1], a + ldh [hMovingBGTilesCounter1], a cp 20 ret c cp 21 @@ -393,7 +393,7 @@ UpdateMovingBgTiles:: ; water - ld hl, vTileset + $14 * $10 + ld hl, vTileset tile $14 ld c, $10 ld a, [wMovingBGTilesCounter2] @@ -417,17 +417,17 @@ UpdateMovingBgTiles:: dec c jr nz, .left .done - ld a, [hTilesetType] + ldh a, [hTilesetType] rrca ret nc ; if in a cave, no flower animations xor a - ld [hMovingBGTilesCounter1], a + ldh [hMovingBGTilesCounter1], a ret .flower xor a - ld [hMovingBGTilesCounter1], a + ldh [hMovingBGTilesCounter1], a ld a, [wMovingBGTilesCounter2] and 3 @@ -438,7 +438,7 @@ UpdateMovingBgTiles:: jr z, .copy ld hl, FlowerTile3 .copy - ld de, vTileset + $3 * $10 + ld de, vTileset tile $03 ld c, $10 .loop ld a, [hli] diff --git a/home/window.asm b/home/window.asm new file mode 100644 index 00000000..e83f9585 --- /dev/null +++ b/home/window.asm @@ -0,0 +1,294 @@ +HandleMenuInput:: + xor a + ld [wPartyMenuAnimMonEnabled], a + +HandleMenuInput_:: + ldh a, [hDownArrowBlinkCount1] + push af + ldh a, [hDownArrowBlinkCount2] + push af ; save existing values on stack + xor a + ldh [hDownArrowBlinkCount1], a ; blinking down arrow timing value 1 + ld a, 6 + ldh [hDownArrowBlinkCount2], 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 + farcall AnimatePartyMon ; shake mini sprite of selected pokemon +.getJoypadState + pop hl + call JoypadLowSensitivity + ldh a, [hJoy5] + and a ; was a key pressed? + jr nz, .keyPressed + push hl + hlcoord 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 + ldh [hDownArrowBlinkCount2], a + pop af + ldh [hDownArrowBlinkCount1], a ; restore previous values + xor a + ld [wMenuWrappingEnabled], a ; disable menu wrapping + ret +.keyPressed + xor a + ld [wCheckFor180DegreeTurn], a + ldh a, [hJoy5] + ld b, a + 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 + ldh 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 + ldh [hDownArrowBlinkCount2], a + pop af + ldh [hDownArrowBlinkCount1], a ; restore previous values + xor a + ld [wMenuWrappingEnabled], a ; disable menu wrapping + ldh 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 + hlcoord 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 + push af + ldh a, [hFlagsFFF6] + bit 1, a ; is the menu double spaced? + jr z, .doubleSpaced1 + ld bc, 20 + jr .getOldMenuItemScreenPosition +.doubleSpaced1 + ld bc, 40 +.getOldMenuItemScreenPosition + pop af +.oldMenuItemLoop + add hl, bc + 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 + push af + ldh a, [hFlagsFFF6] + bit 1, a ; is the menu double spaced? + jr z, .doubleSpaced2 + ld bc, 20 + jr .getCurrentMenuItemScreenPosition +.doubleSpaced2 + ld bc, 40 +.getCurrentMenuItemScreenPosition + pop af +.currentMenuItemLoop + add hl, bc + 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 hDownArrowBlinkCount1 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 + ldh a, [hDownArrowBlinkCount1] + dec a + ldh [hDownArrowBlinkCount1], a + ret nz + ldh a, [hDownArrowBlinkCount2] + dec a + ldh [hDownArrowBlinkCount2], a + ret nz + ld a, " " + ld [hl], a + ld a, $ff + ldh [hDownArrowBlinkCount1], a + ld a, $06 + ldh [hDownArrowBlinkCount2], a + ret +.downArrowOff + ldh a, [hDownArrowBlinkCount1] + and a + ret z + dec a + ldh [hDownArrowBlinkCount1], a + ret nz + dec a + ldh [hDownArrowBlinkCount1], a + ldh a, [hDownArrowBlinkCount2] + dec a + ldh [hDownArrowBlinkCount2], a + ret nz + ld a, $06 + ldh [hDownArrowBlinkCount2], 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:: + bccoord 1, 14 + jp TextCommandProcessor diff --git a/home/yes_no.asm b/home/yes_no.asm index 61aa1390..aae27f86 100644 --- a/home/yes_no.asm +++ b/home/yes_no.asm @@ -14,7 +14,7 @@ Func_35f4:: InitYesNoTextBoxParameters:: xor a ; YES_NO_MENU ld [wTwoOptionMenuID], a - coord hl, 14, 7 + hlcoord 14, 7 ld bc, $80f ret @@ -22,7 +22,7 @@ YesNoChoicePokeCenter:: call SaveScreenTilesToBuffer1 ld a, HEAL_CANCEL_MENU ld [wTwoOptionMenuID], a - coord hl, 11, 6 + hlcoord 11, 6 lb bc, 8, 12 jr DisplayYesNoChoice @@ -30,7 +30,7 @@ WideYesNoChoice:: ; unused call SaveScreenTilesToBuffer1 ld a, WIDE_YES_NO_MENU ld [wTwoOptionMenuID], a - coord hl, 12, 7 + hlcoord 12, 7 lb bc, 8, 13 DisplayYesNoChoice:: |