diff options
Diffstat (limited to 'engine/gfx')
-rw-r--r-- | engine/gfx/cgb_layouts.asm | 981 | ||||
-rw-r--r-- | engine/gfx/color.asm | 1352 | ||||
-rw-r--r-- | engine/gfx/crystal_layouts.asm | 304 | ||||
-rw-r--r-- | engine/gfx/dma_transfer.asm | 604 | ||||
-rw-r--r-- | engine/gfx/load_font.asm | 147 | ||||
-rw-r--r-- | engine/gfx/load_overworld_font.asm | 16 | ||||
-rw-r--r-- | engine/gfx/load_pics.asm | 490 | ||||
-rw-r--r-- | engine/gfx/load_push_oam.asm | 21 | ||||
-rw-r--r-- | engine/gfx/mon_icons.asm | 454 | ||||
-rw-r--r-- | engine/gfx/pic_animation.asm | 1079 | ||||
-rw-r--r-- | engine/gfx/place_graphic.asm | 55 | ||||
-rw-r--r-- | engine/gfx/player_gfx.asm | 224 | ||||
-rw-r--r-- | engine/gfx/sgb_layouts.asm | 571 | ||||
-rw-r--r-- | engine/gfx/sprite_anims.asm | 876 | ||||
-rw-r--r-- | engine/gfx/sprites.asm | 649 | ||||
-rw-r--r-- | engine/gfx/trademon_frontpic.asm | 38 |
16 files changed, 7861 insertions, 0 deletions
diff --git a/engine/gfx/cgb_layouts.asm b/engine/gfx/cgb_layouts.asm new file mode 100644 index 000000000..d8f53d7fc --- /dev/null +++ b/engine/gfx/cgb_layouts.asm @@ -0,0 +1,981 @@ +; Replaces the functionality of sgb.asm to work with CGB hardware. + +CheckCGB: + ld a, [hCGB] + and a + ret + +LoadSGBLayoutCGB: + ld a, b + cp SCGB_RAM + jr nz, .not_ram + ld a, [wSGBPredef] +.not_ram + cp SCGB_PARTY_MENU_HP_PALS + jp z, CGB_ApplyPartyMenuHPPals + call ResetBGPals + ld l, a + ld h, 0 + add hl, hl + ld de, .dw + add hl, de + ld a, [hli] + ld h, [hl] + ld l, a + ld de, .ReturnFromJumpTable + push de + jp hl + +.ReturnFromJumpTable: + ret + +.dw + dw _CGB_BattleGrayscale + dw _CGB_BattleColors + dw _CGB_PokegearPals + dw _CGB_StatsScreenHPPals + dw _CGB_Pokedex + dw _CGB_SlotMachine + dw _CGB06 + dw _CGB_GSIntro + dw _CGB_Diploma + dw _CGB_MapPals + dw _CGB_PartyMenu + dw _CGB_Evolution + dw _CGB_GSTitleScreen + dw _CGB0d + dw _CGB_MoveList + dw _CGB_BetaPikachuMinigame + dw _CGB_PokedexSearchOption + dw _CGB11 + dw _CGB_Pokepic + dw _CGB13 + dw _CGB_PackPals + dw _CGB_TrainerCard + dw _CGB_PokedexUnownMode + dw _CGB_BillsPC + dw _CGB_UnownPuzzle + dw _CGB_GamefreakLogo + dw _CGB_PlayerOrMonFrontpicPals + dw _CGB_TradeTube + dw _CGB_TrainerOrMonFrontpicPals + dw _CGB_MysteryGift + dw _CGB1e + +_CGB_BattleGrayscale: + ld hl, PalPacket_BattleGrayscale + 1 + ld de, wBGPals1 + ld c, 4 + call CopyPalettes + ld hl, PalPacket_BattleGrayscale + 1 + ld de, wBGPals1 palette PAL_BATTLE_BG_EXP + ld c, 4 + call CopyPalettes + ld hl, PalPacket_BattleGrayscale + 1 + ld de, wOBPals1 + ld c, 2 + call CopyPalettes + jr _CGB_FinishBattleScreenLayout + +_CGB_BattleColors: + ld de, wBGPals1 + call GetBattlemonBackpicPalettePointer + push hl + call LoadPalette_White_Col1_Col2_Black ; PAL_BATTLE_BG_PLAYER + call GetEnemyFrontpicPalettePointer + push hl + call LoadPalette_White_Col1_Col2_Black ; PAL_BATTLE_BG_ENEMY + ld a, [wEnemyHPPal] + ld l, a + ld h, $0 + add hl, hl + add hl, hl + ld bc, HPBarPals + add hl, bc + call LoadPalette_White_Col1_Col2_Black ; PAL_BATTLE_BG_ENEMY_HP + ld a, [wPlayerHPPal] + ld l, a + ld h, $0 + add hl, hl + add hl, hl + ld bc, HPBarPals + add hl, bc + call LoadPalette_White_Col1_Col2_Black ; PAL_BATTLE_BG_PLAYER_HP + ld hl, ExpBarPalette + call LoadPalette_White_Col1_Col2_Black ; PAL_BATTLE_BG_EXP + ld de, wOBPals1 + pop hl + call LoadPalette_White_Col1_Col2_Black ; PAL_BATTLE_OB_ENEMY + pop hl + call LoadPalette_White_Col1_Col2_Black ; PAL_BATTLE_OB_PLAYER + ld a, SCGB_BATTLE_COLORS + ld [wSGBPredef], a + call ApplyPals +_CGB_FinishBattleScreenLayout: + call InitPartyMenuBGPal7 + hlcoord 0, 0, wAttrMap + ld bc, SCREEN_WIDTH * SCREEN_HEIGHT + ld a, PAL_BATTLE_BG_ENEMY_HP + call ByteFill + hlcoord 0, 4, wAttrMap + lb bc, 8, 10 + ld a, PAL_BATTLE_BG_PLAYER + call FillBoxCGB + hlcoord 10, 0, wAttrMap + lb bc, 7, 10 + ld a, PAL_BATTLE_BG_ENEMY + call FillBoxCGB + hlcoord 0, 0, wAttrMap + lb bc, 4, 10 + ld a, PAL_BATTLE_BG_ENEMY_HP + call FillBoxCGB + hlcoord 10, 7, wAttrMap + lb bc, 5, 10 + ld a, PAL_BATTLE_BG_PLAYER_HP + call FillBoxCGB + hlcoord 10, 11, wAttrMap + lb bc, 1, 9 + ld a, PAL_BATTLE_BG_EXP + call FillBoxCGB + hlcoord 0, 12, wAttrMap + ld bc, 6 * SCREEN_WIDTH + ld a, PAL_BATTLE_BG_TEXT + call ByteFill + ld hl, BattleObjectPals + ld de, wOBPals1 palette PAL_BATTLE_OB_GRAY + ld bc, 6 palettes + ld a, BANK(wOBPals1) + call FarCopyWRAM + call ApplyAttrMap + ret + +InitPartyMenuBGPal7: + farcall Function100dc0 +Mobile_InitPartyMenuBGPal7: + ld hl, PartyMenuBGPalette + jr nc, .not_mobile + ld hl, PartyMenuBGMobilePalette +.not_mobile + ld de, wBGPals1 palette 7 + ld bc, 1 palettes + ld a, BANK(wBGPals1) + call FarCopyWRAM + ret + +InitPartyMenuBGPal0: + farcall Function100dc0 + ld hl, PartyMenuBGPalette + jr nc, .not_mobile + ld hl, PartyMenuBGMobilePalette +.not_mobile + ld de, wBGPals1 palette 0 + ld bc, 1 palettes + ld a, BANK(wBGPals1) + call FarCopyWRAM + ret + +_CGB_PokegearPals: + ld a, [wPlayerGender] + bit PLAYERGENDER_FEMALE_F, a + jr z, .male + ld hl, FemalePokegearPals + jr .got_pals + +.male + ld hl, MalePokegearPals +.got_pals + ld de, wBGPals1 + ld bc, 6 palettes + ld a, BANK(wBGPals1) + call FarCopyWRAM + call ApplyPals + ld a, $1 + ld [hCGBPalUpdate], a + ret + +_CGB_StatsScreenHPPals: + ld de, wBGPals1 + ld a, [wCurHPPal] + ld l, a + ld h, $0 + add hl, hl + add hl, hl + ld bc, HPBarPals + add hl, bc + call LoadPalette_White_Col1_Col2_Black ; hp palette + ld a, [wCurPartySpecies] + ld bc, wTempMonDVs + call GetPlayerOrMonPalettePointer + call LoadPalette_White_Col1_Col2_Black ; mon palette + ld hl, ExpBarPalette + call LoadPalette_White_Col1_Col2_Black ; exp palette + ld hl, StatsScreenPagePals + ld de, wBGPals1 palette 3 + ld bc, 3 palettes ; pink, green, and blue page palettes + ld a, BANK(wBGPals1) + call FarCopyWRAM + call WipeAttrMap + + hlcoord 0, 0, wAttrMap + lb bc, 8, SCREEN_WIDTH + ld a, $1 ; mon palette + call FillBoxCGB + + hlcoord 10, 16, wAttrMap + ld bc, 10 + ld a, $2 ; exp palette + call ByteFill + + hlcoord 13, 5, wAttrMap + lb bc, 2, 2 + ld a, $3 ; pink page palette + call FillBoxCGB + + hlcoord 15, 5, wAttrMap + lb bc, 2, 2 + ld a, $4 ; green page palette + call FillBoxCGB + + hlcoord 17, 5, wAttrMap + lb bc, 2, 2 + ld a, $5 ; blue page palette + call FillBoxCGB + + call ApplyAttrMap + call ApplyPals + ld a, $1 + ld [hCGBPalUpdate], a + ret + +StatsScreenPagePals: +INCLUDE "gfx/stats/pages.pal" + +StatsScreenPals: +INCLUDE "gfx/stats/stats.pal" + +_CGB_Pokedex: + ld de, wBGPals1 + ld a, PREDEFPAL_POKEDEX + call GetPredefPal + call LoadHLPaletteIntoDE ; dex interface palette + ld a, [wCurPartySpecies] + cp $ff + jr nz, .is_pokemon + ld hl, .PokedexQuestionMarkPalette + call LoadHLPaletteIntoDE ; green question mark palette + jr .got_palette + +.is_pokemon + call GetMonPalettePointer_ + call LoadPalette_White_Col1_Col2_Black ; mon palette +.got_palette + call WipeAttrMap + hlcoord 1, 1, wAttrMap + lb bc, 7, 7 + ld a, $1 ; green question mark palette + call FillBoxCGB + call InitPartyMenuOBPals + ld hl, .PokedexCursorPalette + ld de, wOBPals1 palette 7 ; green cursor palette + ld bc, 1 palettes + ld a, BANK(wOBPals1) + call FarCopyWRAM + call ApplyAttrMap + call ApplyPals + ld a, $1 + ld [hCGBPalUpdate], a + ret + +.PokedexQuestionMarkPalette: +INCLUDE "gfx/pokedex/question_mark.pal" + +.PokedexCursorPalette: +INCLUDE "gfx/pokedex/cursor.pal" + +_CGB_BillsPC: + ld de, wBGPals1 + ld a, PREDEFPAL_POKEDEX + call GetPredefPal + call LoadHLPaletteIntoDE + ld a, [wCurPartySpecies] + cp $ff + jr nz, .GetMonPalette + ld hl, .BillsPCOrangePalette + call LoadHLPaletteIntoDE + jr .Resume + +.GetMonPalette: + ld bc, wTempMonDVs + call GetPlayerOrMonPalettePointer + call LoadPalette_White_Col1_Col2_Black +.Resume: + call WipeAttrMap + hlcoord 1, 4, wAttrMap + lb bc, 7, 7 + ld a, $1 + call FillBoxCGB + call InitPartyMenuOBPals + call ApplyAttrMap + call ApplyPals + ld a, $1 + ld [hCGBPalUpdate], a + ret + +.Function9009: + ld hl, .BillsPCOrangePalette + call LoadHLPaletteIntoDE + jr .asm_901a + +.unused + ld bc, wTempMonDVs + call GetPlayerOrMonPalettePointer + call LoadPalette_White_Col1_Col2_Black +.asm_901a + call WipeAttrMap + hlcoord 1, 1, wAttrMap + lb bc, 7, 7 + ld a, $1 + call FillBoxCGB + call InitPartyMenuOBPals + call ApplyAttrMap + call ApplyPals + ld a, $1 + ld [hCGBPalUpdate], a + ret + +.BillsPCOrangePalette: +INCLUDE "gfx/pc/orange.pal" + +_CGB_PokedexUnownMode: + ld de, wBGPals1 + ld a, PREDEFPAL_POKEDEX + call GetPredefPal + call LoadHLPaletteIntoDE + ld a, [wCurPartySpecies] + call GetMonPalettePointer_ + call LoadPalette_White_Col1_Col2_Black + call WipeAttrMap + hlcoord 7, 5, wAttrMap + lb bc, 7, 7 + ld a, $1 + call FillBoxCGB + call InitPartyMenuOBPals + call ApplyAttrMap + call ApplyPals + ld a, $1 + ld [hCGBPalUpdate], a + ret + +_CGB_SlotMachine: + ld hl, SlotMachinePals + ld de, wBGPals1 + ld bc, 16 palettes + ld a, BANK(wBGPals1) + call FarCopyWRAM + call WipeAttrMap + hlcoord 0, 2, wAttrMap + lb bc, 10, 3 + ld a, $2 + call FillBoxCGB + hlcoord 17, 2, wAttrMap + lb bc, 10, 3 + ld a, $2 + call FillBoxCGB + hlcoord 0, 4, wAttrMap + lb bc, 6, 3 + ld a, $3 + call FillBoxCGB + hlcoord 17, 4, wAttrMap + lb bc, 6, 3 + ld a, $3 + call FillBoxCGB + hlcoord 0, 6, wAttrMap + lb bc, 2, 3 + ld a, $4 + call FillBoxCGB + hlcoord 17, 6, wAttrMap + lb bc, 2, 3 + ld a, $4 + call FillBoxCGB + hlcoord 4, 2, wAttrMap + lb bc, 2, 12 + ld a, $1 + call FillBoxCGB + hlcoord 3, 2, wAttrMap + lb bc, 10, 1 + ld a, $1 + call FillBoxCGB + hlcoord 16, 2, wAttrMap + lb bc, 10, 1 + ld a, $1 + call FillBoxCGB + hlcoord 0, 12, wAttrMap + ld bc, $78 + ld a, $7 + call ByteFill + call ApplyAttrMap + call ApplyPals + ld a, $1 + ld [hCGBPalUpdate], a + ret + +_CGB06: + ld hl, PalPacket_SCGB_06 + 1 + call CopyFourPalettes + call WipeAttrMap + ld de, wOBPals1 + ld a, PREDEFPAL_PACK + call GetPredefPal + call LoadHLPaletteIntoDE + hlcoord 0, 6, wAttrMap + lb bc, 12, SCREEN_WIDTH + ld a, $1 + call FillBoxCGB + call ApplyAttrMap + call ApplyPals + ld a, $1 + ld [hCGBPalUpdate], a + ret + +_CGB_GSIntro: + ld b, 0 + ld hl, .Jumptable + add hl, bc + add hl, bc + ld a, [hli] + ld h, [hl] + ld l, a + jp hl + +.Jumptable: + dw .ShellderLaprasScene + dw .JigglypuffPikachuScene + dw .StartersCharizardScene + +.ShellderLaprasScene: + ld hl, .ShellderLaprasBGPalette + ld de, wBGPals1 + call LoadHLPaletteIntoDE + ld hl, .ShellderLaprasOBPals + ld de, wOBPals1 + ld bc, 2 palettes + ld a, BANK(wOBPals1) + call FarCopyWRAM + call WipeAttrMap + ret + +.ShellderLaprasBGPalette: + RGB 19, 31, 19 + RGB 18, 23, 31 + RGB 11, 21, 28 + RGB 04, 16, 24 + +.ShellderLaprasOBPals: + RGB 29, 29, 29 + RGB 20, 19, 20 + RGB 19, 06, 04 + RGB 03, 04, 06 + + RGB 31, 31, 31 + RGB 31, 31, 31 + RGB 31, 00, 00 + RGB 03, 04, 06 + +.JigglypuffPikachuScene: + ld de, wBGPals1 + ld a, PREDEFPAL_GS_INTRO_JIGGLYPUFF_PIKACHU_BG + call GetPredefPal + call LoadHLPaletteIntoDE + + ld de, wOBPals1 + ld a, PREDEFPAL_GS_INTRO_JIGGLYPUFF_PIKACHU_OB + call GetPredefPal + call LoadHLPaletteIntoDE + call WipeAttrMap + ret + +.StartersCharizardScene: + ld hl, PalPacket_Pack + 1 + call CopyFourPalettes + ld de, wOBPals1 + ld a, PREDEFPAL_GS_INTRO_STARTERS_TRANSITION + call GetPredefPal + call LoadHLPaletteIntoDE + call WipeAttrMap + ret + +_CGB11: + ld hl, BetaPokerPals + ld de, wBGPals1 + ld bc, 5 palettes + ld a, BANK(wBGPals1) + call FarCopyWRAM + call ApplyPals + call WipeAttrMap + call ApplyAttrMap + ret + +_CGB_Diploma: + ld hl, DiplomaPalettes + ld de, wBGPals1 + ld bc, 16 palettes + ld a, BANK(wBGPals1) + call FarCopyWRAM + + ld hl, PalPacket_Diploma + 1 + call CopyFourPalettes + call WipeAttrMap + call ApplyAttrMap + ret + +_CGB_MapPals: + call LoadMapPals + ld a, SCGB_MAPPALS + ld [wSGBPredef], a + ret + +_CGB_PartyMenu: + ld hl, PalPacket_PartyMenu + 1 + call CopyFourPalettes + call InitPartyMenuBGPal0 + call InitPartyMenuBGPal7 + call InitPartyMenuOBPals + call ApplyAttrMap + ret + +_CGB_Evolution: + ld de, wBGPals1 + ld a, c + and a + jr z, .pokemon + ld a, PREDEFPAL_BLACKOUT + call GetPredefPal + call LoadHLPaletteIntoDE + jr .got_palette + +.pokemon + ld hl, wPartyMon1DVs + ld bc, PARTYMON_STRUCT_LENGTH + ld a, [wCurPartyMon] + call AddNTimes + ld c, l + ld b, h + ld a, [wPlayerHPPal] + call GetPlayerOrMonPalettePointer + call LoadPalette_White_Col1_Col2_Black + ld hl, BattleObjectPals + ld de, wOBPals1 palette PAL_BATTLE_OB_GRAY + ld bc, 6 palettes + ld a, BANK(wOBPals1) + call FarCopyWRAM + +.got_palette + call WipeAttrMap + call ApplyAttrMap + call ApplyPals + ld a, $1 + ld [hCGBPalUpdate], a + ret + +_CGB_GSTitleScreen: + ld hl, UnusedGSTitleBGPals + ld de, wBGPals1 + ld bc, 5 palettes + ld a, BANK(wBGPals1) + call FarCopyWRAM + ld hl, UnusedGSTitleOBPals + ld de, wOBPals1 + ld bc, 2 palettes + ld a, BANK(wOBPals1) + call FarCopyWRAM + ld a, SCGB_DIPLOMA + ld [wSGBPredef], a + call ApplyPals + ld a, $1 + ld [hCGBPalUpdate], a + ret + +_CGB0d: + ld hl, PalPacket_Diploma + 1 + call CopyFourPalettes + call WipeAttrMap + call ApplyAttrMap + ret + +_CGB_UnownPuzzle: + ld hl, PalPacket_UnownPuzzle + 1 + call CopyFourPalettes + ld de, wOBPals1 + ld a, PREDEFPAL_UNOWN_PUZZLE + call GetPredefPal + call LoadHLPaletteIntoDE + ld a, [rSVBK] + push af + ld a, BANK(wOBPals1) + ld [rSVBK], a + ld hl, wOBPals1 + ld a, LOW(palred 31 + palgreen 0 + palblue 0) + ld [hli], a + ld a, HIGH(palred 31 + palgreen 0 + palblue 0) + ld [hl], a + pop af + ld [rSVBK], a + call WipeAttrMap + call ApplyAttrMap + ret + +_CGB_TrainerCard: + ld de, wBGPals1 + xor a ; CHRIS + call GetTrainerPalettePointer + call LoadPalette_White_Col1_Col2_Black + ld a, FALKNER ; KRIS + call GetTrainerPalettePointer + call LoadPalette_White_Col1_Col2_Black + ld a, BUGSY + call GetTrainerPalettePointer + call LoadPalette_White_Col1_Col2_Black + ld a, WHITNEY + call GetTrainerPalettePointer + call LoadPalette_White_Col1_Col2_Black + ld a, MORTY + call GetTrainerPalettePointer + call LoadPalette_White_Col1_Col2_Black + ld a, CHUCK + call GetTrainerPalettePointer + call LoadPalette_White_Col1_Col2_Black + ld a, JASMINE + call GetTrainerPalettePointer + call LoadPalette_White_Col1_Col2_Black + ld a, PRYCE + call GetTrainerPalettePointer + call LoadPalette_White_Col1_Col2_Black + ld a, PREDEFPAL_CGB_BADGE + call GetPredefPal + call LoadHLPaletteIntoDE + + ; fill screen with opposite-gender palette for the card border + hlcoord 0, 0, wAttrMap + ld bc, SCREEN_WIDTH * SCREEN_HEIGHT + ld a, [wPlayerGender] + and a + ld a, $1 ; kris + jr z, .got_gender + ld a, $0 ; chris +.got_gender + call ByteFill + ; fill trainer sprite area with same-gender palette + hlcoord 14, 1, wAttrMap + lb bc, 7, 5 + ld a, [wPlayerGender] + and a + ld a, $0 ; chris + jr z, .got_gender2 + ld a, $1 ; kris +.got_gender2 + call FillBoxCGB + ; top-right corner still uses the border's palette + hlcoord 18, 1, wAttrMap + ld [hl], $1 + hlcoord 2, 11, wAttrMap + lb bc, 2, 4 + ld a, $1 ; falkner + call FillBoxCGB + hlcoord 6, 11, wAttrMap + lb bc, 2, 4 + ld a, $2 ; bugsy + call FillBoxCGB + hlcoord 10, 11, wAttrMap + lb bc, 2, 4 + ld a, $3 ; whitney + call FillBoxCGB + hlcoord 14, 11, wAttrMap + lb bc, 2, 4 + ld a, $4 ; morty + call FillBoxCGB + hlcoord 2, 14, wAttrMap + lb bc, 2, 4 + ld a, $5 ; chuck + call FillBoxCGB + hlcoord 6, 14, wAttrMap + lb bc, 2, 4 + ld a, $6 ; jasmine + call FillBoxCGB + hlcoord 10, 14, wAttrMap + lb bc, 2, 4 + ld a, $7 ; pryce + call FillBoxCGB + ; clair uses kris's palette + ld a, [wPlayerGender] + and a + push af + jr z, .got_gender3 + hlcoord 14, 14, wAttrMap + lb bc, 2, 4 + ld a, $1 + call FillBoxCGB +.got_gender3 + pop af + ld c, $0 + jr nz, .got_gender4 + inc c +.got_gender4 + ld a, c + hlcoord 18, 1, wAttrMap + ld [hl], a + call ApplyAttrMap + call ApplyPals + ld a, $1 + ld [hCGBPalUpdate], a + ret + +_CGB_MoveList: + ld de, wBGPals1 + ld a, PREDEFPAL_GOLDENROD + call GetPredefPal + call LoadHLPaletteIntoDE + ld a, [wPlayerHPPal] + ld l, a + ld h, 0 + add hl, hl + add hl, hl + ld bc, HPBarPals + add hl, bc + call LoadPalette_White_Col1_Col2_Black + call WipeAttrMap + hlcoord 11, 1, wAttrMap + lb bc, 2, 9 + ld a, $1 + call FillBoxCGB + call ApplyAttrMap + call ApplyPals + ld a, $1 + ld [hCGBPalUpdate], a + ret + +_CGB_BetaPikachuMinigame: + ld hl, PalPacket_BetaPikachuMinigame + 1 + call CopyFourPalettes + call WipeAttrMap + call ApplyAttrMap + call ApplyPals + ld a, $1 + ld [hCGBPalUpdate], a + ret + +_CGB_PokedexSearchOption: + ld de, wBGPals1 + ld a, PREDEFPAL_POKEDEX + call GetPredefPal + call LoadHLPaletteIntoDE + call WipeAttrMap + call ApplyAttrMap + call ApplyPals + ld a, $1 + ld [hCGBPalUpdate], a + ret + +_CGB_PackPals: +; pack pals + ld a, [wBattleType] + cp BATTLETYPE_TUTORIAL + jr z, .tutorial_male + + ld a, [wPlayerGender] + bit PLAYERGENDER_FEMALE_F, a + jr z, .tutorial_male + + ld hl, .KrisPackPals + jr .got_gender + +.tutorial_male + ld hl, .ChrisPackPals + +.got_gender + ld de, wBGPals1 + ld bc, 8 palettes ; 6 palettes? + ld a, BANK(wBGPals1) + call FarCopyWRAM + call WipeAttrMap + hlcoord 0, 0, wAttrMap + lb bc, 1, 10 + ld a, $1 + call FillBoxCGB + hlcoord 10, 0, wAttrMap + lb bc, 1, 10 + ld a, $2 + call FillBoxCGB + hlcoord 7, 2, wAttrMap + lb bc, 9, 1 + ld a, $3 + call FillBoxCGB + hlcoord 0, 7, wAttrMap + lb bc, 3, 5 + ld a, $4 + call FillBoxCGB + hlcoord 0, 3, wAttrMap + lb bc, 3, 5 + ld a, $5 + call FillBoxCGB + call ApplyAttrMap + call ApplyPals + ld a, $1 + ld [hCGBPalUpdate], a + ret + +.ChrisPackPals: +INCLUDE "gfx/pack/pack.pal" + +.KrisPackPals: +INCLUDE "gfx/pack/pack_f.pal" + +_CGB_Pokepic: + call _CGB_MapPals + ld de, SCREEN_WIDTH + hlcoord 0, 0, wAttrMap + ld a, [wMenuBorderTopCoord] +.loop + and a + jr z, .found_top + dec a + add hl, de + jr .loop + +.found_top + ld a, [wMenuBorderLeftCoord] + ld e, a + ld d, $0 + add hl, de + ld a, [wMenuBorderTopCoord] + ld b, a + ld a, [wMenuBorderBottomCoord] + inc a + sub b + ld b, a + ld a, [wMenuBorderLeftCoord] + ld c, a + ld a, [wMenuBorderRightCoord] + sub c + inc a + ld c, a + ld a, $0 + call FillBoxCGB + call ApplyAttrMap + ret + +_CGB13: + ld hl, PalPacket_SCGB_13 + 1 + call CopyFourPalettes + call WipeAttrMap + hlcoord 0, 4, wAttrMap + lb bc, 10, SCREEN_WIDTH + ld a, $2 + call FillBoxCGB + hlcoord 0, 6, wAttrMap + lb bc, 6, SCREEN_WIDTH + ld a, $1 + call FillBoxCGB + call ApplyAttrMap + call ApplyPals + ld a, $1 + ld [hCGBPalUpdate], a + ret + +_CGB_GamefreakLogo: + ld de, wBGPals1 + ld a, PREDEFPAL_GAMEFREAK_LOGO + call GetPredefPal + call LoadHLPaletteIntoDE + ld hl, .Palette + ld de, wOBPals1 + call LoadHLPaletteIntoDE + ld hl, .Palette + ld de, wOBPals1 palette 1 + call LoadHLPaletteIntoDE + call WipeAttrMap + call ApplyAttrMap + call ApplyPals + ret + +.Palette: +INCLUDE "gfx/splash/logo.pal" + +_CGB_PlayerOrMonFrontpicPals: + ld de, wBGPals1 + ld a, [wCurPartySpecies] + ld bc, wTempMonDVs + call GetPlayerOrMonPalettePointer + call LoadPalette_White_Col1_Col2_Black + call WipeAttrMap + call ApplyAttrMap + call ApplyPals + ret + +_CGB1e: + ld de, wBGPals1 + ld a, [wCurPartySpecies] + call GetMonPalettePointer_ + call LoadPalette_White_Col1_Col2_Black + call WipeAttrMap + call ApplyAttrMap + ret + +_CGB_TradeTube: + ld hl, PalPacket_TradeTube + 1 + call CopyFourPalettes + ld hl, PartyMenuOBPals + ld de, wOBPals1 + ld bc, 1 palettes + ld a, BANK(wOBPals1) + call FarCopyWRAM + ld de, wOBPals1 palette 7 + ld a, PREDEFPAL_TRADE_TUBE + call GetPredefPal + call LoadHLPaletteIntoDE + call WipeAttrMap + ret + +_CGB_TrainerOrMonFrontpicPals: + ld de, wBGPals1 + ld a, [wCurPartySpecies] + ld bc, wTempMonDVs + call GetFrontpicPalettePointer + call LoadPalette_White_Col1_Col2_Black + call WipeAttrMap + call ApplyAttrMap + call ApplyPals + ret + +_CGB_MysteryGift: + ld hl, .Palettes + ld de, wBGPals1 + ld bc, 2 palettes + ld a, BANK(wBGPals1) + call FarCopyWRAM + call ApplyPals + call WipeAttrMap + hlcoord 3, 7, wAttrMap + lb bc, 8, 14 + ld a, $1 + call FillBoxCGB + hlcoord 1, 5, wAttrMap + lb bc, 1, 18 + ld a, $1 + call FillBoxCGB + hlcoord 1, 16, wAttrMap + lb bc, 1, 18 + ld a, $1 + call FillBoxCGB + hlcoord 0, 0, wAttrMap + lb bc, 17, 2 + ld a, $1 + call FillBoxCGB + hlcoord 18, 5, wAttrMap + lb bc, 12, 1 + ld a, $1 + call FillBoxCGB + call ApplyAttrMap + ret + +.Palettes: +INCLUDE "gfx/mystery_gift/mystery_gift.pal" diff --git a/engine/gfx/color.asm b/engine/gfx/color.asm new file mode 100644 index 000000000..9a3b4f8ef --- /dev/null +++ b/engine/gfx/color.asm @@ -0,0 +1,1352 @@ +INCLUDE "engine/gfx/sgb_layouts.asm" + +SHINY_ATK_BIT EQU 5 +SHINY_DEF_VAL EQU 10 +SHINY_SPD_VAL EQU 10 +SHINY_SPC_VAL EQU 10 + +CheckShininess: +; Check if a mon is shiny by DVs at bc. +; Return carry if shiny. + + ld l, c + ld h, b + +; Attack + ld a, [hl] + and 1 << SHINY_ATK_BIT + jr z, .NotShiny + +; Defense + ld a, [hli] + and $f + cp SHINY_DEF_VAL + jr nz, .NotShiny + +; Speed + ld a, [hl] + and $f0 + cp SHINY_SPD_VAL << 4 + jr nz, .NotShiny + +; Special + ld a, [hl] + and $f + cp SHINY_SPC_VAL + jr nz, .NotShiny + +.Shiny: + scf + ret + +.NotShiny: + and a + ret + +Unused_CheckShininess: +; Return carry if the DVs at hl are all 10 or higher. + +; Attack + ld a, [hl] + cp 10 << 4 + jr c, .NotShiny + +; Defense + ld a, [hli] + and $f + cp 10 + jr c, .NotShiny + +; Speed + ld a, [hl] + cp 10 << 4 + jr c, .NotShiny + +; Special + ld a, [hl] + and $f + cp 10 + jr c, .NotShiny + +.Shiny: + scf + ret + +.NotShiny: + and a + ret + +Unreferenced_Function8aa4: + push de + push bc + ld hl, PalPacket_9ce6 + ld de, wSGBPals + ld bc, PALPACKET_LENGTH + call CopyBytes + pop bc + pop de + ld a, c + ld [wSGBPals + 3], a + ld a, b + ld [wSGBPals + 4], a + ld a, e + ld [wSGBPals + 5], a + ld a, d + ld [wSGBPals + 6], a + ld hl, wSGBPals + call PushSGBPals_ + ld hl, BlkPacket_9a86 + call PushSGBPals_ + ret + +InitPartyMenuPalettes: + ld hl, PalPacket_PartyMenu + 1 + call CopyFourPalettes + call InitPartyMenuOBPals + call WipeAttrMap + ret + +; SGB layout for SCGB_PARTY_MENU_HP_PALS +SGB_ApplyPartyMenuHPPals: + ld hl, wHPPals + ld a, [wSGBPals] + ld e, a + ld d, $0 + add hl, de + ld e, l + ld d, h + ld a, [de] + and a + ld e, $5 + jr z, .okay + dec a + ld e, $a + jr z, .okay + ld e, $f +.okay + push de + ld hl, wSGBPals + 10 + ld bc, $6 + ld a, [wSGBPals] + call AddNTimes + pop de + ld [hl], e + ret + +Unreferenced_Function8b07: + call CheckCGB + ret z +; CGB only + ld hl, .BGPal + ld de, wBGPals1 + ld bc, 1 palettes + ld a, BANK(wBGPals1) + call FarCopyWRAM + + ld hl, .OBPal + ld de, wOBPals1 + ld bc, 1 palettes + ld a, BANK(wOBPals1) + call FarCopyWRAM + + call ApplyPals + ld a, $1 + ld [hCGBPalUpdate], a + ret + +.BGPal: + RGB 31, 31, 31 + RGB 18, 23, 31 + RGB 15, 20, 31 + RGB 00, 00, 00 + +.OBPal: + RGB 31, 31, 31 + RGB 31, 31, 12 + RGB 08, 16, 28 + RGB 00, 00, 00 + +Unreferenced_Function8b3f: + call CheckCGB + ret nz + ld a, [hSGB] + and a + ret z + ld hl, BlkPacket_9a86 + jp PushSGBPals_ + +Unreferenced_Function8b4d: + call CheckCGB + jr nz, .cgb + ld a, [hSGB] + and a + ret z + ld hl, PalPacket_BetaIntroVenusaur + jp PushSGBPals_ + +.cgb + ld de, wOBPals1 + ld a, PREDEFPAL_BETA_INTRO_VENUSAUR + call GetPredefPal + jp LoadHLPaletteIntoDE + +Unreferenced_Function8b67: + call CheckCGB + jr nz, .cgb + ld a, [hSGB] + and a + ret z + ld hl, PalPacket_Pack + jp PushSGBPals_ + +.cgb + ld de, wOBPals1 + ld a, PREDEFPAL_PACK + call GetPredefPal + jp LoadHLPaletteIntoDE + +Unreferenced_Function8b81: + call CheckCGB + jr nz, .cgb + ld a, [hSGB] + and a + ret z + ld a, c + push af + ld hl, PalPacket_9ce6 + ld de, wSGBPals + ld bc, PALPACKET_LENGTH + call CopyBytes + pop af + call GetMonPalettePointer_ + ld a, [hli] + ld [wSGBPals + 3], a + ld a, [hli] + ld [wSGBPals + 4], a + ld a, [hli] + ld [wSGBPals + 5], a + ld a, [hl] + ld [wSGBPals + 6], a + ld hl, wSGBPals + jp PushSGBPals_ + +.cgb + ld de, wOBPals1 + ld a, c + call GetMonPalettePointer_ + call LoadPalette_White_Col1_Col2_Black + ret + +LoadTrainerClassPaletteAsNthBGPal: + ld a, [wTrainerClass] + call GetTrainerPalettePointer + ld a, e + jr got_palette_pointer_8bd7 + +LoadMonPaletteAsNthBGPal: + ld a, [wCurPartySpecies] + call GetMonPalettePointer + ld a, e + bit 7, a + jr z, got_palette_pointer_8bd7 + and $7f + inc hl + inc hl + inc hl + inc hl + +got_palette_pointer_8bd7 + push hl + ld hl, wBGPals1 + ld de, 1 palettes +.loop + and a + jr z, .got_addr + add hl, de + dec a + jr .loop + +.got_addr + ld e, l + ld d, h + pop hl + call LoadPalette_White_Col1_Col2_Black + ret + +Unreferenced_Function8bec: + ld a, [hCGB] + and a + jr nz, .cgb + ld hl, wPlayerLightScreenCount + jp PushSGBPals_ + +.cgb + ld a, [wEnemyLightScreenCount] ; col + ld c, a + ld a, [wEnemyReflectCount] ; row + hlcoord 0, 0, wAttrMap + ld de, SCREEN_WIDTH +.loop + and a + jr z, .done + add hl, de + dec a + jr .loop + +.done + ld b, $0 + add hl, bc + lb bc, 6, 4 + ld a, [wEnemySafeguardCount] ; value + and $3 + call FillBoxCGB + call CopyTilemapAtOnce + ret + +ApplyMonOrTrainerPals: + call CheckCGB + ret z + ld a, e + and a + jr z, .get_trainer + ld a, [wCurPartySpecies] + call GetMonPalettePointer_ + jr .load_palettes + +.get_trainer + ld a, [wTrainerClass] + call GetTrainerPalettePointer + +.load_palettes + ld de, wBGPals1 + call LoadPalette_White_Col1_Col2_Black + call WipeAttrMap + call ApplyAttrMap + call ApplyPals + ret + +ApplyHPBarPals: + ld a, [wWhichHPBar] + and a + jr z, .Enemy + cp $1 + jr z, .Player + cp $2 + jr z, .PartyMenu + ret + +.Enemy: + ld de, wBGPals2 palette PAL_BATTLE_BG_ENEMY_HP color 1 + jr .okay + +.Player: + ld de, wBGPals2 palette PAL_BATTLE_BG_PLAYER_HP color 1 + +.okay + ld l, c + ld h, $0 + add hl, hl + add hl, hl + ld bc, HPBarPals + add hl, bc + ld bc, 4 + ld a, BANK(wBGPals2) + call FarCopyWRAM + ld a, $1 + ld [hCGBPalUpdate], a + ret + +.PartyMenu: + ld e, c + inc e + hlcoord 11, 1, wAttrMap + ld bc, 2 * SCREEN_WIDTH + ld a, [wCurPartyMon] +.loop + and a + jr z, .done + add hl, bc + dec a + jr .loop + +.done + lb bc, 2, 8 + ld a, e + call FillBoxCGB + ret + +LoadStatsScreenPals: + call CheckCGB + ret z + ld hl, StatsScreenPals + ld b, 0 + dec c + add hl, bc + add hl, bc + ld a, [rSVBK] + push af + ld a, BANK(wBGPals1) + ld [rSVBK], a + ld a, [hli] + ld [wBGPals1 palette 0], a + ld [wBGPals1 palette 2], a + ld a, [hl] + ld [wBGPals1 palette 0 + 1], a + ld [wBGPals1 palette 2 + 1], a + pop af + ld [rSVBK], a + call ApplyPals + ld a, $1 + ret + +LoadMailPalettes: + ld l, e + ld h, 0 + add hl, hl + add hl, hl + add hl, hl + ld de, .MailPals + add hl, de + call CheckCGB + jr nz, .cgb + push hl + ld hl, PalPacket_9ce6 + ld de, wSGBPals + ld bc, PALPACKET_LENGTH + call CopyBytes + pop hl + inc hl + inc hl + ld a, [hli] + ld [wSGBPals + 3], a + ld a, [hli] + ld [wSGBPals + 4], a + ld a, [hli] + ld [wSGBPals + 5], a + ld a, [hli] + ld [wSGBPals + 6], a + ld hl, wSGBPals + call PushSGBPals_ + ld hl, BlkPacket_9a86 + call PushSGBPals_ + ret + +.cgb + ld de, wBGPals1 + ld bc, 1 palettes + ld a, BANK(wBGPals1) + call FarCopyWRAM + call ApplyPals + call WipeAttrMap + call ApplyAttrMap + ret + +.MailPals: +INCLUDE "gfx/mail/mail.pal" + +INCLUDE "engine/gfx/cgb_layouts.asm" + +Unreferenced_Function95f0: + ld hl, .Palette + ld de, wBGPals1 + ld bc, 1 palettes + ld a, BANK(wBGPals1) + call FarCopyWRAM + call ApplyPals + call WipeAttrMap + call ApplyAttrMap + ret + +.Palette: + RGB 31, 31, 31 + RGB 09, 31, 31 + RGB 10, 12, 31 + RGB 00, 03, 19 + +CopyFourPalettes: + ld de, wBGPals1 + ld c, 4 + +CopyPalettes: +.loop + push bc + ld a, [hli] + push hl + call GetPredefPal + call LoadHLPaletteIntoDE + pop hl + inc hl + pop bc + dec c + jr nz, .loop + ret + +GetPredefPal: + ld l, a + ld h, $0 + add hl, hl + add hl, hl + add hl, hl + ld bc, PredefPals + add hl, bc + ret + +LoadHLPaletteIntoDE: + ld a, [rSVBK] + push af + ld a, BANK(wOBPals1) + ld [rSVBK], a + ld c, 1 palettes +.loop + ld a, [hli] + ld [de], a + inc de + dec c + jr nz, .loop + pop af + ld [rSVBK], a + ret + +LoadPalette_White_Col1_Col2_Black: + ld a, [rSVBK] + push af + ld a, BANK(wBGPals1) + ld [rSVBK], a + + ld a, LOW(PALRGB_WHITE) + ld [de], a + inc de + ld a, HIGH(PALRGB_WHITE) + ld [de], a + inc de + + ld c, 2 * PAL_COLOR_SIZE +.loop + ld a, [hli] + ld [de], a + inc de + dec c + jr nz, .loop + + xor a + ld [de], a + inc de + ld [de], a + inc de + + pop af + ld [rSVBK], a + ret + +FillBoxCGB: +.row + push bc + push hl +.col + ld [hli], a + dec c + jr nz, .col + pop hl + ld bc, SCREEN_WIDTH + add hl, bc + pop bc + dec b + jr nz, .row + ret + +ResetBGPals: + push af + push bc + push de + push hl + + ld a, [rSVBK] + push af + ld a, BANK(wBGPals1) + ld [rSVBK], a + + ld hl, wBGPals1 + ld c, 1 palettes +.loop + ld a, $ff + ld [hli], a + ld [hli], a + ld [hli], a + ld [hli], a + xor a + ld [hli], a + ld [hli], a + ld [hli], a + ld [hli], a + dec c + jr nz, .loop + + pop af + ld [rSVBK], a + + pop hl + pop de + pop bc + pop af + ret + +WipeAttrMap: + hlcoord 0, 0, wAttrMap + ld bc, SCREEN_WIDTH * SCREEN_HEIGHT + xor a + call ByteFill + ret + +ApplyPals: + ld hl, wBGPals1 + ld de, wBGPals2 + ld bc, 16 palettes + ld a, BANK(wGBCPalettes) + call FarCopyWRAM + ret + +ApplyAttrMap: + ld a, [rLCDC] + bit rLCDC_ENABLE, a + jr z, .UpdateVBank1 + ld a, [hBGMapMode] + push af + ld a, $2 + ld [hBGMapMode], a + call DelayFrame + call DelayFrame + call DelayFrame + call DelayFrame + pop af + ld [hBGMapMode], a + ret + +.UpdateVBank1: + hlcoord 0, 0, wAttrMap + debgcoord 0, 0 + ld b, SCREEN_HEIGHT + ld a, $1 + ld [rVBK], a +.row + ld c, SCREEN_WIDTH +.col + ld a, [hli] + ld [de], a + inc de + dec c + jr nz, .col + ld a, BG_MAP_WIDTH - SCREEN_WIDTH + add e + jr nc, .okay + inc d +.okay + ld e, a + dec b + jr nz, .row + ld a, $0 + ld [rVBK], a + ret + +; CGB layout for SCGB_PARTY_MENU_HP_PALS +CGB_ApplyPartyMenuHPPals: + ld hl, wHPPals + ld a, [wSGBPals] + ld e, a + ld d, $0 + add hl, de + ld e, l + ld d, h + ld a, [de] + inc a + ld e, a + hlcoord 11, 2, wAttrMap + ld bc, 2 * SCREEN_WIDTH + ld a, [wSGBPals] +.loop + and a + jr z, .done + add hl, bc + dec a + jr .loop +.done + lb bc, 2, 8 + ld a, e + call FillBoxCGB + ret + +InitPartyMenuOBPals: + ld hl, PartyMenuOBPals + ld de, wOBPals1 + ld bc, 2 palettes + ld a, BANK(wOBPals1) + call FarCopyWRAM + ret + +GetBattlemonBackpicPalettePointer: + push de + farcall GetPartyMonDVs + ld c, l + ld b, h + ld a, [wTempBattleMonSpecies] + call GetPlayerOrMonPalettePointer + pop de + ret + +GetEnemyFrontpicPalettePointer: + push de + farcall GetEnemyMonDVs + ld c, l + ld b, h + ld a, [wTempEnemyMonSpecies] + call GetFrontpicPalettePointer + pop de + ret + +GetPlayerOrMonPalettePointer: + and a + jp nz, GetMonNormalOrShinyPalettePointer + ld a, [wPlayerSpriteSetupFlags] + bit PLAYERSPRITESETUP_FEMALE_TO_MALE_F, a + jr nz, .male + ld a, [wPlayerGender] + and a + jr z, .male + ld hl, KrisPalette + ret + +.male + ld hl, PlayerPalette + ret + +GetFrontpicPalettePointer: + and a + jp nz, GetMonNormalOrShinyPalettePointer + ld a, [wTrainerClass] + +GetTrainerPalettePointer: + ld l, a + ld h, 0 + add hl, hl + add hl, hl + ld bc, TrainerPalettes + add hl, bc + ret + +GetMonPalettePointer_: + call GetMonPalettePointer + ret + +Unreferenced_Function9779: + ret + call CheckCGB + ret z + ld hl, BattleObjectPals + ld a, $90 + ld [rOBPI], a + ld c, 6 palettes +.loop + ld a, [hli] + ld [rOBPD], a + dec c + jr nz, .loop + ld hl, BattleObjectPals + ld de, wOBPals1 palette 2 + ld bc, 2 palettes + ld a, BANK(wOBPals1) + call FarCopyWRAM + ret + +BattleObjectPals: +INCLUDE "gfx/battle_anims/battle_anims.pal" + +Unreferenced_Function97cc: + call CheckCGB + ret z + ld a, $90 + ld [rOBPI], a + ld a, PREDEFPAL_TRADE_TUBE + call GetPredefPal + call .PushPalette + ld a, PREDEFPAL_RB_GREENMON + call GetPredefPal + call .PushPalette + ret + +.PushPalette: + ld c, 1 palettes +.loop + ld a, [hli] + ld [rOBPD], a + dec c + jr nz, .loop + ret + +GetMonPalettePointer: + ld l, a + ld h, $0 + add hl, hl + add hl, hl + add hl, hl + ld bc, PokemonPalettes + add hl, bc + ret + +GetMonNormalOrShinyPalettePointer: + push bc + call GetMonPalettePointer + pop bc + push hl + call CheckShininess + pop hl + ret nc +rept 4 + inc hl +endr + ret + +PushSGBPals_: + ld a, [wcfbe] + push af + set 7, a + ld [wcfbe], a + call PushSGBPals + pop af + ld [wcfbe], a + ret + +PushSGBPals: + ld a, [hl] + and $7 + ret z + ld b, a +.loop + push bc + xor a + ld [rJOYP], a + ld a, $30 + ld [rJOYP], a + ld b, $10 +.loop2 + ld e, $8 + ld a, [hli] + ld d, a +.loop3 + bit 0, d + ld a, $10 + jr nz, .okay + ld a, $20 +.okay + ld [rJOYP], a + ld a, $30 + ld [rJOYP], a + rr d + dec e + jr nz, .loop3 + dec b + jr nz, .loop2 + ld a, $20 + ld [rJOYP], a + ld a, $30 + ld [rJOYP], a + call SGBDelayCycles + pop bc + dec b + jr nz, .loop + ret + +InitSGBBorder: + call CheckCGB + ret nz +; SGB/DMG only + di + ld a, [wcfbe] + push af + set 7, a + ld [wcfbe], a + xor a + ld [rJOYP], a + ld [hSGB], a + call PushSGBBorderPalsAndWait + jr nc, .skip + ld a, $1 + ld [hSGB], a + call _InitSGBBorderPals + call SGBBorder_PushBGPals + call SGBDelayCycles + call SGB_ClearVRAM + call PushSGBBorder + call SGBDelayCycles + call SGB_ClearVRAM + ld hl, MaskEnCancelPacket + call PushSGBPals + +.skip + pop af + ld [wcfbe], a + ei + ret + +InitCGBPals:: + call CheckCGB + ret z +; CGB only + ld a, BANK(vTiles3) + ld [rVBK], a + ld hl, vTiles3 + ld bc, $200 tiles + xor a + call ByteFill + ld a, BANK(vTiles0) + ld [rVBK], a + ld a, 1 << rBGPI_AUTO_INCREMENT + ld [rBGPI], a + ld c, 4 * 8 +.bgpals_loop + ld a, LOW(PALRGB_WHITE) + ld [rBGPD], a + ld a, HIGH(PALRGB_WHITE) + ld [rBGPD], a + dec c + jr nz, .bgpals_loop + ld a, 1 << rOBPI_AUTO_INCREMENT + ld [rOBPI], a + ld c, 4 * 8 +.obpals_loop + ld a, LOW(PALRGB_WHITE) + ld [rOBPD], a + ld a, HIGH(PALRGB_WHITE) + ld [rOBPD], a + dec c + jr nz, .obpals_loop + ld a, [rSVBK] + push af + ld a, BANK(wBGPals1) + ld [rSVBK], a + ld hl, wBGPals1 + call .LoadWhitePals + ld hl, wBGPals2 + call .LoadWhitePals + pop af + ld [rSVBK], a + ret + +.LoadWhitePals: + ld c, 4 * 16 +.loop + ld a, LOW(PALRGB_WHITE) + ld [hli], a + ld a, HIGH(PALRGB_WHITE) + ld [hli], a + dec c + jr nz, .loop + ret + +_InitSGBBorderPals: + ld hl, .PacketPointerTable + ld c, 9 +.loop + push bc + ld a, [hli] + push hl + ld h, [hl] + ld l, a + call PushSGBPals + pop hl + inc hl + pop bc + dec c + jr nz, .loop + ret + +.PacketPointerTable: + dw MaskEnFreezePacket + dw DataSndPacket1 + dw DataSndPacket2 + dw DataSndPacket3 + dw DataSndPacket4 + dw DataSndPacket5 + dw DataSndPacket6 + dw DataSndPacket7 + dw DataSndPacket8 + +Unreferenced_Function9911: + di + xor a + ld [rJOYP], a + ld hl, MaskEnFreezePacket + call PushSGBPals + call PushSGBBorder + call SGBDelayCycles + call SGB_ClearVRAM + ld hl, MaskEnCancelPacket + call PushSGBPals + ei + ret + +PushSGBBorder: + call .LoadSGBBorderPointers + push de + call SGBBorder_YetMorePalPushing + pop hl + call SGBBorder_MorePalPushing + ret + +.LoadSGBBorderPointers: + ld hl, SGBBorder + ld de, SGBBorderMap + ret + +SGB_ClearVRAM: + ld hl, VRAM_Begin + ld bc, VRAM_End - VRAM_Begin + xor a + call ByteFill + ret + +PushSGBBorderPalsAndWait: + ld hl, MltReq2Packet + call PushSGBPals + call SGBDelayCycles + ld a, [rJOYP] + and $3 + cp $3 + jr nz, .carry + ld a, $20 + ld [rJOYP], a + ld a, [rJOYP] + ld a, [rJOYP] + call SGBDelayCycles + call SGBDelayCycles + ld a, $30 + ld [rJOYP], a + call SGBDelayCycles + call SGBDelayCycles + ld a, $10 + ld [rJOYP], a +rept 6 + ld a, [rJOYP] +endr + call SGBDelayCycles + call SGBDelayCycles + ld a, $30 + ld [rJOYP], a + ld a, [rJOYP] + ld a, [rJOYP] + ld a, [rJOYP] + call SGBDelayCycles + call SGBDelayCycles + ld a, [rJOYP] + and $3 + cp $3 + jr nz, .carry + call .FinalPush + and a + ret + +.carry + call .FinalPush + scf + ret + +.FinalPush: + ld hl, MltReq1Packet + call PushSGBPals + jp SGBDelayCycles + +SGBBorder_PushBGPals: + call DisableLCD + ld a, %11100100 + ld [rBGP], a + ld hl, PredefPals + ld de, vTiles1 + ld bc, $100 tiles + call CopyData + call DrawDefaultTiles + ld a, LCDC_DEFAULT + ld [rLCDC], a + ld hl, PalTrnPacket + call PushSGBPals + xor a + ld [rBGP], a + ret + +SGBBorder_MorePalPushing: + call DisableLCD + ld a, $e4 + ld [rBGP], a + ld de, vTiles1 + ld bc, 20 tiles + call CopyData + ld b, 18 +.loop + push bc + ld bc, $c + call CopyData + ld bc, $28 + call ClearBytes + ld bc, $c + call CopyData + pop bc + dec b + jr nz, .loop + ld bc, $140 + call CopyData + ld bc, Start + call ClearBytes + ld bc, 16 palettes + call CopyData + call DrawDefaultTiles + ld a, LCDC_DEFAULT + ld [rLCDC], a + ld hl, PctTrnPacket + call PushSGBPals + xor a + ld [rBGP], a + ret + +SGBBorder_YetMorePalPushing: + call DisableLCD + ld a, %11100100 + ld [rBGP], a + ld de, vTiles1 + ld b, $80 +.loop + push bc + ld bc, 1 tiles + call CopyData + ld bc, 1 tiles + call ClearBytes + pop bc + dec b + jr nz, .loop + call DrawDefaultTiles + ld a, LCDC_DEFAULT + ld [rLCDC], a + ld hl, ChrTrnPacket + call PushSGBPals + xor a + ld [rBGP], a + ret + +CopyData: +; copy bc bytes of data from hl to de +.loop + ld a, [hli] + ld [de], a + inc de + dec bc + ld a, c + or b + jr nz, .loop + ret + +ClearBytes: +; clear bc bytes of data starting from de +.loop + xor a + ld [de], a + inc de + dec bc + ld a, c + or b + jr nz, .loop + ret + +DrawDefaultTiles: +; Draw 240 tiles (2/3 of the screen) from tiles in VRAM + hlbgcoord 0, 0 ; BG Map 0 + ld de, BG_MAP_WIDTH - SCREEN_WIDTH + ld a, $80 ; starting tile + ld c, 12 + 1 +.line + ld b, 20 +.tile + ld [hli], a + inc a + dec b + jr nz, .tile +; next line + add hl, de + dec c + jr nz, .line + ret + +SGBDelayCycles: + ld de, 7000 +.wait + nop + nop + nop + dec de + ld a, d + or e + jr nz, .wait + ret + +INCLUDE "gfx/sgb/blk_packets.asm" +INCLUDE "gfx/sgb/pal_packets.asm" +INCLUDE "data/sgb_ctrl_packets.asm" + +PredefPals: +INCLUDE "gfx/sgb/predef.pal" + +SGBBorderMap: +; interleaved tile ids and palette ids +INCBIN "gfx/sgb/sgb_border.bin" + +SGBBorderPalettes: +INCLUDE "gfx/sgb/sgb_border.pal" + +SGBBorder: +INCBIN "gfx/sgb/sgb_border.2bpp" + +HPBarPals: +INCLUDE "gfx/battle/hp_bar.pal" + +ExpBarPalette: +INCLUDE "gfx/battle/exp_bar.pal" + +INCLUDE "data/pokemon/palettes.asm" + +INCLUDE "data/trainers/palettes.asm" + +LoadMapPals: + farcall LoadSpecialMapPalette + jr c, .got_pals + + ; Which palette group is based on whether we're outside or inside + ld a, [wEnvironment] + and 7 + ld e, a + ld d, 0 + ld hl, EnvironmentColorsPointers + add hl, de + add hl, de + ld a, [hli] + ld h, [hl] + ld l, a + ; Futher refine by time of day + ld a, [wTimeOfDayPal] + maskbits NUM_DAYTIMES + add a + add a + add a + ld e, a + ld d, 0 + add hl, de + ld e, l + ld d, h + ; Switch to palettes WRAM bank + ld a, [rSVBK] + push af + ld a, BANK(wBGPals1) + ld [rSVBK], a + ld hl, wBGPals1 + ld b, 8 +.outer_loop + ld a, [de] ; lookup index for TilesetBGPalette + push de + push hl + ld l, a + ld h, 0 + add hl, hl + add hl, hl + add hl, hl + ld de, TilesetBGPalette + add hl, de + ld e, l + ld d, h + pop hl + ld c, 1 palettes +.inner_loop + ld a, [de] + inc de + ld [hli], a + dec c + jr nz, .inner_loop + pop de + inc de + dec b + jr nz, .outer_loop + pop af + ld [rSVBK], a + +.got_pals + ld a, [wTimeOfDayPal] + maskbits NUM_DAYTIMES + ld bc, 8 palettes + ld hl, MapObjectPals + call AddNTimes + ld de, wOBPals1 + ld bc, 8 palettes + ld a, BANK(wOBPals1) + call FarCopyWRAM + + ld a, [wEnvironment] + cp TOWN + jr z, .outside + cp ROUTE + ret nz +.outside + ld a, [wMapGroup] + ld l, a + ld h, 0 + add hl, hl + add hl, hl + add hl, hl + ld de, RoofPals + add hl, de + ld a, [wTimeOfDayPal] + maskbits NUM_DAYTIMES + cp NITE_F + jr c, .morn_day +rept 4 + inc hl +endr +.morn_day + ld de, wBGPals1 palette PAL_BG_ROOF color 1 + ld bc, 4 + ld a, BANK(wBGPals1) + call FarCopyWRAM + ret + +INCLUDE "data/maps/environment_colors.asm" + +PartyMenuBGMobilePalette: +INCLUDE "gfx/stats/party_menu_bg_mobile.pal" + +PartyMenuBGPalette: +INCLUDE "gfx/stats/party_menu_bg.pal" + +TilesetBGPalette: +INCLUDE "gfx/tilesets/bg_tiles.pal" + +MapObjectPals:: +INCLUDE "gfx/overworld/npc_sprites.pal" + +RoofPals: +INCLUDE "gfx/tilesets/roofs.pal" + +DiplomaPalettes: +INCLUDE "gfx/diploma/diploma.pal" + +PartyMenuOBPals: +INCLUDE "gfx/stats/party_menu_ob.pal" + +UnusedGSTitleBGPals: +INCLUDE "gfx/title/unused_gs_bg.pal" + +UnusedGSTitleOBPals: +INCLUDE "gfx/title/unused_gs_fg.pal" + +MalePokegearPals: +INCLUDE "gfx/pokegear/pokegear.pal" + +FemalePokegearPals: +INCLUDE "gfx/pokegear/pokegear_f.pal" + +BetaPokerPals: +INCLUDE "gfx/beta_poker/beta_poker.pal" + +SlotMachinePals: +INCLUDE "gfx/slots/slots.pal" diff --git a/engine/gfx/crystal_layouts.asm b/engine/gfx/crystal_layouts.asm new file mode 100644 index 000000000..b9686701c --- /dev/null +++ b/engine/gfx/crystal_layouts.asm @@ -0,0 +1,304 @@ +GetMysteryGift_MobileAdapterLayout: + ld a, b + cp SCGB_RAM + jr nz, .not_ram + ld a, [wSGBPredef] +.not_ram + push af + farcall ResetBGPals + pop af + ld l, a + ld h, 0 + add hl, hl + ld de, .dw + add hl, de + ld a, [hli] + ld h, [hl] + ld l, a + ld de, .done + push de + jp hl +.done + ret + +.dw + dw MG_Mobile_Layout00 + dw MG_Mobile_Layout01 + dw MG_Mobile_Layout02 + +MG_Mobile_Layout_FillBox: +.row + push bc + push hl +.col + ld [hli], a + dec c + jr nz, .col + pop hl + ld bc, SCREEN_WIDTH + add hl, bc + pop bc + dec b + jr nz, .row + ret + +MG_Mobile_Layout_WipeAttrMap: + hlcoord 0, 0, wAttrMap + ld bc, SCREEN_HEIGHT * SCREEN_WIDTH + xor a + call ByteFill + ret + +MG_Mobile_Layout_LoadPals: + ld de, wBGPals1 + ld hl, Palette_MysteryGiftMobile + ld bc, 5 palettes + ld a, BANK(wBGPals1) + call FarCopyWRAM + ld de, wBGPals1 palette PAL_BG_TEXT + ld hl, Palette_TextBG7 + ld bc, 1 palettes + ld a, BANK(wBGPals1) + call FarCopyWRAM + ret + +MG_Mobile_Layout00: + call MG_Mobile_Layout_LoadPals + call MG_Mobile_Layout_WipeAttrMap + call MG_Mobile_Layout_CreatePalBoxes + farcall ApplyAttrMap + farcall ApplyPals + ret + +MG_Mobile_Layout_CreatePalBoxes: + hlcoord 0, 0, wAttrMap + lb bc, 4, 1 + ld a, $1 + call MG_Mobile_Layout_FillBox + lb bc, 2, 1 + ld a, $2 + call MG_Mobile_Layout_FillBox + lb bc, 6, 1 + ld a, $3 + call MG_Mobile_Layout_FillBox + hlcoord 1, 0, wAttrMap + ld a, $1 + lb bc, 3, 18 + call MG_Mobile_Layout_FillBox + lb bc, 2, 18 + ld a, $2 + call MG_Mobile_Layout_FillBox + lb bc, 12, 18 + ld a, $3 + call MG_Mobile_Layout_FillBox + hlcoord 19, 0, wAttrMap + lb bc, 4, 1 + ld a, $1 + call MG_Mobile_Layout_FillBox + lb bc, 2, 1 + ld a, $2 + call MG_Mobile_Layout_FillBox + lb bc, 6, 1 + ld a, $3 + call MG_Mobile_Layout_FillBox + hlcoord 0, 12, wAttrMap + ld bc, 6 * SCREEN_WIDTH + ld a, $7 + call ByteFill + ret + +Palette_MysteryGiftMobile: +INCLUDE "gfx/mystery_gift/mg_mobile.pal" + +LoadOW_BGPal7:: + ld hl, Palette_TextBG7 + ld de, wBGPals1 palette PAL_BG_TEXT + ld bc, 1 palettes + ld a, BANK(wBGPals1) + call FarCopyWRAM + ret + +Palette_TextBG7: +INCLUDE "gfx/font/bg_text.pal" + +Function49420:: + ld hl, MansionPalette1 + 8 palettes + ld de, wBGPals1 palette PAL_BG_ROOF + ld bc, 1 palettes + ld a, BANK(wBGPals1) + call FarCopyWRAM + ret + +MG_Mobile_Layout01: + call MG_Mobile_Layout_LoadPals + ld de, wBGPals1 palette PAL_BG_TEXT + ld hl, .Palette_49478 + ld bc, 1 palettes + ld a, BANK(wBGPals1) + call FarCopyWRAM + call MG_Mobile_Layout_WipeAttrMap + hlcoord 0, 0, wAttrMap + ld bc, SCREEN_WIDTH * SCREEN_HEIGHT + xor a + call ByteFill + hlcoord 0, 14, wAttrMap + ld bc, 4 * SCREEN_WIDTH + ld a, $7 + call ByteFill + ld a, [wd002] + bit 6, a + jr z, .asm_49464 + call Function49480 + jr .asm_49467 + +.asm_49464 + call Function49496 + +.asm_49467 + farcall ApplyAttrMap + farcall ApplyPals + ld a, $1 + ld [hCGBPalUpdate], a + ret + +.Palette_49478: + RGB 31, 31, 31 + RGB 26, 31, 00 + RGB 20, 16, 03 + RGB 00, 00, 00 + +Function49480: + hlcoord 0, 0, wAttrMap + lb bc, 4, SCREEN_WIDTH + ld a, $7 + call MG_Mobile_Layout_FillBox + hlcoord 0, 2, wAttrMap + ld a, $4 + ld [hl], a + hlcoord 19, 2, wAttrMap + ld [hl], a + ret + +Function49496: + hlcoord 0, 0, wAttrMap + lb bc, 2, SCREEN_WIDTH + ld a, $7 + call MG_Mobile_Layout_FillBox + hlcoord 0, 1, wAttrMap + ld a, $4 + ld [hl], a + hlcoord 19, 1, wAttrMap + ld [hl], a + ret + +INCLUDE "engine/tilesets/tileset_palettes.asm" + +MG_Mobile_Layout02: + ld hl, .Palette_49732 + ld de, wBGPals1 + ld bc, 1 palettes + ld a, BANK(wBGPals1) + call FarCopyWRAM + farcall ApplyPals + call MG_Mobile_Layout_WipeAttrMap + farcall ApplyAttrMap + ld hl, .Palette_4973a + ld de, wOBPals1 + ld bc, 1 palettes + ld a, BANK(wOBPals1) + call FarCopyWRAM + ret + +.Palette_49732: + RGB 31, 31, 31 + RGB 23, 16, 07 + RGB 23, 07, 07 + RGB 03, 07, 20 + +.Palette_4973a: + RGB 00, 00, 00 + RGB 07, 05, 31 + RGB 14, 18, 31 + RGB 31, 31, 31 + +Function49742: + ld hl, .Palette_49757 + ld de, wBGPals1 + ld bc, 8 palettes + ld a, BANK(wBGPals1) + call FarCopyWRAM + farcall ApplyPals + ret + +.Palette_49757: +INCLUDE "gfx/unknown/49757.pal" + +_InitMG_Mobile_LinkTradePalMap: + hlcoord 0, 0, wAttrMap + lb bc, 16, 2 + ld a, $4 + call MG_Mobile_Layout_FillBox + ld a, $3 + ldcoord_a 0, 1, wAttrMap + ldcoord_a 0, 14, wAttrMap + hlcoord 2, 0, wAttrMap + lb bc, 8, 18 + ld a, $5 + call MG_Mobile_Layout_FillBox + hlcoord 2, 8, wAttrMap + lb bc, 8, 18 + ld a, $6 + call MG_Mobile_Layout_FillBox + hlcoord 0, 16, wAttrMap + lb bc, 2, SCREEN_WIDTH + ld a, $4 + call MG_Mobile_Layout_FillBox + ld a, $3 + lb bc, 6, 1 + hlcoord 6, 1, wAttrMap + call MG_Mobile_Layout_FillBox + ld a, $3 + lb bc, 6, 1 + hlcoord 17, 1, wAttrMap + call MG_Mobile_Layout_FillBox + ld a, $3 + lb bc, 6, 1 + hlcoord 6, 9, wAttrMap + call MG_Mobile_Layout_FillBox + ld a, $3 + lb bc, 6, 1 + hlcoord 17, 9, wAttrMap + call MG_Mobile_Layout_FillBox + ld a, $2 + hlcoord 2, 16, wAttrMap + ld [hli], a + ld a, $7 + ld [hli], a + ld [hli], a + ld [hli], a + ld a, $2 + ld [hl], a + hlcoord 2, 17, wAttrMap + ld a, $3 + ld bc, 6 + call ByteFill + ret + +LoadTradeRoomBGPals: + ld hl, TradeRoomPalette + ld de, wBGPals1 palette PAL_BG_GREEN + ld bc, 6 palettes + ld a, BANK(wBGPals1) + call FarCopyWRAM + farcall ApplyPals + ret + +TradeRoomPalette: +INCLUDE "gfx/trade/border.pal" + +InitMG_Mobile_LinkTradePalMap: + call _InitMG_Mobile_LinkTradePalMap + ret + +; unused +INCLUDE "gfx/unknown/4985a.asm" diff --git a/engine/gfx/dma_transfer.asm b/engine/gfx/dma_transfer.asm new file mode 100644 index 000000000..241649dc5 --- /dev/null +++ b/engine/gfx/dma_transfer.asm @@ -0,0 +1,604 @@ +HDMATransferAttrMapAndTileMapToWRAMBank3:: + ld hl, .Function + jp CallInSafeGFXMode + +.Function: + decoord 0, 0, wAttrMap + ld hl, wScratchAttrMap + call PadAttrMapForHDMATransfer + decoord 0, 0 + ld hl, wScratchTileMap + call PadTilemapForHDMATransfer + ld a, $0 + ld [rVBK], a + ld hl, wScratchTileMap + call HDMATransferToWRAMBank3 + ld a, $1 + ld [rVBK], a + ld hl, wScratchAttrMap + call HDMATransferToWRAMBank3 + ret + +HDMATransferTileMapToWRAMBank3:: + ld hl, .Function + jp CallInSafeGFXMode + +.Function: + decoord 0, 0 + ld hl, wScratchTileMap + call PadTilemapForHDMATransfer + ld a, $0 + ld [rVBK], a + ld hl, wScratchTileMap + call HDMATransferToWRAMBank3 + ret + +HDMATransferAttrMapToWRAMBank3: + ld hl, .Function + jp CallInSafeGFXMode + +.Function: + decoord 0, 0, wAttrMap + ld hl, wScratchAttrMap + call PadAttrMapForHDMATransfer + ld a, $1 + ld [rVBK], a + ld hl, wScratchAttrMap + call HDMATransferToWRAMBank3 + ret + +ReloadMapPart:: + ld hl, .Function + jp CallInSafeGFXMode + +.Function: + decoord 0, 0, wAttrMap + ld hl, wScratchAttrMap + call PadAttrMapForHDMATransfer + decoord 0, 0 + ld hl, wScratchTileMap + call PadTilemapForHDMATransfer + call DelayFrame + + di + ld a, [rVBK] + push af + ld a, $1 + ld [rVBK], a + ld hl, wScratchAttrMap + call HDMATransfer_Wait127Scanlines_toBGMap + ld a, $0 + ld [rVBK], a + ld hl, wScratchTileMap + call HDMATransfer_Wait127Scanlines_toBGMap + pop af + ld [rVBK], a + ei + + ret + +Mobile_ReloadMapPart: + ld hl, ReloadMapPart ; useless + ld hl, .Function + jp CallInSafeGFXMode + +.Function: + decoord 0, 0, wAttrMap + ld hl, wScratchAttrMap + call PadAttrMapForHDMATransfer + decoord 0, 0 + ld hl, wScratchTileMap + call PadTilemapForHDMATransfer + call DelayFrame + + di + ld a, [rVBK] + push af + ld a, $1 + ld [rVBK], a + ld hl, wScratchAttrMap + call HDMATransfer_NoDI + ld a, $0 + ld [rVBK], a + ld hl, wScratchTileMap + call HDMATransfer_NoDI + pop af + ld [rVBK], a + ei + + ret + +; unused + ld hl, .unreferenced_1040da + jp CallInSafeGFXMode + +.unreferenced_1040da + ld a, $1 + ld [rVBK], a + ld a, BANK(w3_d800) + ld [rSVBK], a + ld de, w3_d800 + ld a, [hBGMapAddress + 1] + ld [rHDMA1], a + ld a, [hBGMapAddress] + ld [rHDMA2], a + ld a, d + ld [rHDMA3], a + ld a, e + ld [rHDMA4], a + ld a, $23 + ld [hDMATransfer], a + call WaitDMATransfer + ret + +; unused + ld hl, .unreferenced_104101 + jp CallInSafeGFXMode + +.unreferenced_104101 + ld a, $1 + ld [rVBK], a + ld a, BANK(w3_d800) + ld [rSVBK], a + ld hl, w3_d800 + call HDMATransferToWRAMBank3 + ret + +OpenAndCloseMenu_HDMATransferTileMapAndAttrMap:: +; OpenText + ld hl, .Function + jp CallInSafeGFXMode + +.Function: + ; Transfer wAttrMap and Tilemap to BGMap + ; Fill vBGAttrs with $00 + ; Fill vBGTiles with " " + decoord 0, 0, wAttrMap + ld hl, wScratchAttrMap + call PadAttrMapForHDMATransfer + decoord 0, 0 + ld hl, wScratchTileMap + call PadTilemapForHDMATransfer + call DelayFrame + + di + ld a, [rVBK] + push af + ld a, $1 + ld [rVBK], a + ld hl, wScratchAttrMap + call HDMATransfer_Wait123Scanlines_toBGMap + ld a, $0 + ld [rVBK], a + ld hl, wScratchTileMap + call HDMATransfer_Wait123Scanlines_toBGMap + pop af + ld [rVBK], a + ei + ret + +Mobile_OpenAndCloseMenu_HDMATransferTileMapAndAttrMap: + ld hl, .Function + jp CallInSafeGFXMode + +.Function: + ; Transfer wAttrMap and Tilemap to BGMap + ; Fill vBGAttrs with $00 + ; Fill vBGTiles with $ff + decoord 0, 0, wAttrMap + ld hl, wScratchAttrMap + call PadAttrMapForHDMATransfer + ld c, $ff + decoord 0, 0 + ld hl, wScratchTileMap + call PadMapForHDMATransfer + + ld a, $1 + ld [rVBK], a + ld hl, wScratchAttrMap + call HDMATransfer_Wait127Scanlines_toBGMap + ld a, $0 + ld [rVBK], a + ld hl, wScratchTileMap + call HDMATransfer_Wait127Scanlines_toBGMap + ret + +CallInSafeGFXMode: + ld a, [hBGMapMode] + push af + ld a, [hMapAnims] + push af + xor a + ld [hBGMapMode], a + ld [hMapAnims], a + ld a, [rSVBK] + push af + ld a, BANK(wScratchTileMap) + ld [rSVBK], a + ld a, [rVBK] + push af + + call ._hl_ + + pop af + ld [rVBK], a + pop af + ld [rSVBK], a + pop af + ld [hMapAnims], a + pop af + ld [hBGMapMode], a + ret + +._hl_ + jp hl + +HDMATransferToWRAMBank3: + call _LoadHDMAParameters + ld a, $23 + ld [hDMATransfer], a + +WaitDMATransfer: +.loop + call DelayFrame + ld a, [hDMATransfer] + and a + jr nz, .loop + ret + +HDMATransfer_Wait127Scanlines_toBGMap: +; HDMA transfer from hl to [hBGMapAddress] +; hBGMapAddress -> de +; 2 * SCREEN_HEIGHT -> c + ld a, [hBGMapAddress + 1] + ld d, a + ld a, [hBGMapAddress] + ld e, a + ld c, 2 * SCREEN_HEIGHT + jr HDMATransfer_Wait127Scanlines + +HDMATransfer_Wait123Scanlines_toBGMap: +; HDMA transfer from hl to [hBGMapAddress] +; hBGMapAddress -> de +; 2 * SCREEN_HEIGHT -> c +; $7b --> b + ld a, [hBGMapAddress + 1] + ld d, a + ld a, [hBGMapAddress] + ld e, a + ld c, 2 * SCREEN_HEIGHT + jr HDMATransfer_Wait123Scanlines + +HDMATransfer_NoDI: +; HDMA transfer from hl to [hBGMapAddress] +; [hBGMapAddress] --> de +; 2 * SCREEN_HEIGHT --> c + ld a, [hBGMapAddress + 1] + ld d, a + ld a, [hBGMapAddress] + ld e, a + ld c, 2 * SCREEN_HEIGHT + + ; [rHDMA1, rHDMA2] = hl & $fff0 + ld a, h + ld [rHDMA1], a + ld a, l + and $f0 + ld [rHDMA2], a + ; [rHDMA3, rHDMA4] = de & $1ff0 + ld a, d + and $1f + ld [rHDMA3], a + ld a, e + and $f0 + ld [rHDMA4], a + ; b = c | %10000000 + ld a, c + dec c + or $80 + ld b, a + ; d = $7f - c + 1 + ld a, $7f + sub c + ld d, a + ; while [rLY] >= d: pass +.loop1 + ld a, [rLY] + cp d + jr nc, .loop1 + ; while not [rSTAT] & 3: pass +.loop2 + ld a, [rSTAT] + and $3 + jr z, .loop2 + ; load the 5th byte of HDMA + ld a, b + ld [rHDMA5], a + ; wait until rLY advances (c + 1) times + ld a, [rLY] + inc c + ld hl, rLY +.loop3 + cp [hl] + jr z, .loop3 + ld a, [hl] + dec c + jr nz, .loop3 + ld hl, rHDMA5 + res 7, [hl] + ret + +HDMATransfer_Wait123Scanlines: + ld b, $7b + jr _continue_HDMATransfer + +HDMATransfer_Wait127Scanlines: + ld b, $7f +_continue_HDMATransfer: +; a lot of waiting around for hardware registers + ; [rHDMA1, rHDMA2] = hl & $fff0 + ld a, h + ld [rHDMA1], a + ld a, l + and $f0 ; high nybble + ld [rHDMA2], a + ; [rHDMA3, rHDMA4] = de & $1ff0 + ld a, d + and $1f ; lower 5 bits + ld [rHDMA3], a + ld a, e + and $f0 ; high nybble + ld [rHDMA4], a + ; e = c | %10000000 + ld a, c + dec c + or $80 + ld e, a + ; d = b - c + 1 + ld a, b + sub c + ld d, a + ; while [rLY] >= d: pass +.ly_loop + ld a, [rLY] + cp d + jr nc, .ly_loop + + di + ; while [rSTAT] & 3: pass +.rstat_loop_1 + ld a, [rSTAT] + and $3 + jr nz, .rstat_loop_1 + ; while not [rSTAT] & 3: pass +.rstat_loop_2 + ld a, [rSTAT] + and $3 + jr z, .rstat_loop_2 + ; load the 5th byte of HDMA + ld a, e + ld [rHDMA5], a + ; wait until rLY advances (c + 1) times + ld a, [rLY] + inc c + ld hl, rLY +.final_ly_loop + cp [hl] + jr z, .final_ly_loop + ld a, [hl] + dec c + jr nz, .final_ly_loop + ld hl, rHDMA5 + res 7, [hl] + ei + + ret + +_LoadHDMAParameters: + ld a, h + ld [rHDMA1], a + ld a, l + ld [rHDMA2], a + ld a, [hBGMapAddress + 1] + and $1f + ld [rHDMA3], a + ld a, [hBGMapAddress] + ld [rHDMA4], a + ret + +PadTilemapForHDMATransfer: + ld c, " " + jr PadMapForHDMATransfer + +PadAttrMapForHDMATransfer: + ld c, $0 + +PadMapForHDMATransfer: +; pad a 20x18 map to 32x18 for HDMA transfer +; back up the padding value in c to hMapObjectIndexBuffer + ld a, [hMapObjectIndexBuffer] + push af + ld a, c + ld [hMapObjectIndexBuffer], a + +; for each row on the screen + ld c, SCREEN_HEIGHT +.loop1 +; for each tile in the row + ld b, SCREEN_WIDTH +.loop2 +; copy from de to hl + ld a, [de] + inc de + ld [hli], a + dec b + jr nz, .loop2 + +; load the original padding value of c into hl for 32 - 20 = 12 rows + ld a, [hMapObjectIndexBuffer] + ld b, BG_MAP_WIDTH - SCREEN_WIDTH +.loop3 + ld [hli], a + dec b + jr nz, .loop3 + + dec c + jr nz, .loop1 + +; restore the original value of hMapObjectIndexBuffer + pop af + ld [hMapObjectIndexBuffer], a + ret + +_Get2bpp:: + ; 2bpp when [rLCDC] & $80 + ; switch to WRAM bank 6 + ld a, [rSVBK] + push af + ld a, BANK(wScratchTileMap) + ld [rSVBK], a + + push bc + push hl + + ; Copy c tiles of the 2bpp from b:de to wScratchTileMap + ld a, b ; bank + ld l, c ; number of tiles + ld h, $0 + ; multiply by 16 (16 bytes of a 2bpp = 8 x 8 tile) + add hl, hl + add hl, hl + add hl, hl + add hl, hl + ld b, h + ld c, l + ld h, d ; address + ld l, e + ld de, wScratchTileMap + call FarCopyBytes + + pop hl + pop bc + + push bc + call DelayFrame + pop bc + + ld d, h + ld e, l + ld hl, wScratchTileMap + call HDMATransfer_Wait127Scanlines + + ; restore the previous bank + pop af + ld [rSVBK], a + ret + +_Get1bpp:: + ; 1bpp when [rLCDC] & $80 +.loop + ld a, c + cp $10 + jp c, .bankswitch + jp z, .bankswitch + push bc + push hl + push de + ld c, $10 + call .bankswitch + pop de + ld hl, $80 + add hl, de + ld d, h + ld e, l + pop hl + lb bc, 1, 0 + add hl, bc + pop bc + ld a, c + sub $10 + ld c, a + jr .loop + +.bankswitch + ld a, [rSVBK] + push af + ld a, BANK(wScratchTileMap) + ld [rSVBK], a + + push bc + push hl + + ld a, b + ld l, c + ld h, $0 + add hl, hl ; multiply by 8 + add hl, hl ; multiply by 8 + add hl, hl ; multiply by 8 + ld c, l + ld b, h + ld h, d + ld l, e + ld de, wScratchTileMap + call FarCopyBytesDouble_DoubleBankSwitch + + pop hl + pop bc + + push bc + call DelayFrame + pop bc + + ld d, h + ld e, l + ld hl, wScratchTileMap + call HDMATransfer_Wait127Scanlines + + pop af + ld [rSVBK], a + ret + +HDMATransfer_OnlyTopFourRows: + ld hl, .Function + jp CallInSafeGFXMode + +.Function: + ld hl, wScratchTileMap + decoord 0, 0 + call .Copy + ld hl, wScratchTileMap + $80 + decoord 0, 0, wAttrMap + call .Copy + ld a, $1 + ld [rVBK], a + ld c, $8 + ld hl, wScratchTileMap + $80 + debgcoord 0, 0, vBGMap1 + call HDMATransfer_Wait127Scanlines + ld a, $0 + ld [rVBK], a + ld c, $8 + ld hl, wScratchTileMap + debgcoord 0, 0, vBGMap1 + call HDMATransfer_Wait127Scanlines + ret + +.Copy: + ld b, 4 +.outer_loop + ld c, SCREEN_WIDTH +.inner_loop + ld a, [de] + ld [hli], a + inc de + dec c + jr nz, .inner_loop + ld a, l + add BG_MAP_WIDTH - SCREEN_WIDTH + ld l, a + ld a, h + adc 0 + ld h, a + dec b + jr nz, .outer_loop + ret diff --git a/engine/gfx/load_font.asm b/engine/gfx/load_font.asm new file mode 100644 index 000000000..41c0721d6 --- /dev/null +++ b/engine/gfx/load_font.asm @@ -0,0 +1,147 @@ +INCLUDE "gfx/font.asm" + +; This and the following two functions are unreferenced. +; Debug, perhaps? +Unreferenced_fb434: + db 0 + +Unreferenced_Functionfb435: + ld a, [Unreferenced_fb434] + and a + jp nz, Get1bpp_2 + jp Get1bpp + +Unreferenced_Functionfb43f: + ld a, [Unreferenced_fb434] + and a + jp nz, Get2bpp_2 + jp Get2bpp +; End unreferenced block + +_LoadStandardFont:: + ld de, Font + ld hl, vTiles1 + lb bc, BANK(Font), 128 ; "A" to "9" + ld a, [rLCDC] + bit rLCDC_ENABLE, a + jp z, Copy1bpp + + ld de, Font + ld hl, vTiles1 + lb bc, BANK(Font), 32 ; "A" to "]" + call Get1bpp_2 + ld de, Font + 32 * LEN_1BPP_TILE + ld hl, vTiles1 tile $20 + lb bc, BANK(Font), 32 ; "a" to $bf + call Get1bpp_2 + ld de, Font + 64 * LEN_1BPP_TILE + ld hl, vTiles1 tile $40 + lb bc, BANK(Font), 32 ; "Ä" to "←" + call Get1bpp_2 + ld de, Font + 96 * LEN_1BPP_TILE + ld hl, vTiles1 tile $60 + lb bc, BANK(Font), 32 ; "'" to "9" + call Get1bpp_2 + ret + +_LoadFontsExtra1:: + ld de, FontsExtra_SolidBlackGFX + ld hl, vTiles2 tile "■" ; $60 + lb bc, BANK(FontsExtra_SolidBlackGFX), 1 + call Get1bpp_2 + ld de, PokegearPhoneIconGFX + ld hl, vTiles2 tile "☎" ; $62 + lb bc, BANK(PokegearPhoneIconGFX), 1 + call Get2bpp_2 + ld de, FontExtra + 3 tiles ; "<BOLD_D>" + ld hl, vTiles2 tile "<BOLD_D>" + lb bc, BANK(FontExtra), 22 ; "<BOLD_D>" to "ぉ" + call Get2bpp_2 + jr LoadFrame + +_LoadFontsExtra2:: + ld de, FontsExtra2_UpArrowGFX + ld hl, vTiles2 tile "▲" ; $61 + ld b, BANK(FontsExtra2_UpArrowGFX) + ld c, 1 + call Get2bpp_2 + ret + +_LoadFontsBattleExtra:: + ld de, FontBattleExtra + ld hl, vTiles2 tile $60 + lb bc, BANK(FontBattleExtra), 25 + call Get2bpp_2 + jr LoadFrame + +LoadFrame: + ld a, [wTextBoxFrame] + maskbits NUM_FRAMES + ld bc, 6 * LEN_1BPP_TILE + ld hl, Frames + call AddNTimes + ld d, h + ld e, l + ld hl, vTiles2 tile "┌" ; $79 + lb bc, BANK(Frames), 6 ; "┌" to "┘" + call Get1bpp_2 + ld hl, vTiles2 tile " " ; $7f + ld de, TextBoxSpaceGFX + lb bc, BANK(TextBoxSpaceGFX), 1 + call Get1bpp_2 + ret + +LoadBattleFontsHPBar: + ld de, FontBattleExtra + ld hl, vTiles2 tile $60 + lb bc, BANK(FontBattleExtra), 12 + call Get2bpp_2 + ld hl, vTiles2 tile $70 + ld de, FontBattleExtra + 16 tiles ; "<DO>" + lb bc, BANK(FontBattleExtra), 3 ; "<DO>" to "『" + call Get2bpp_2 + call LoadFrame + +LoadHPBar: + ld de, EnemyHPBarBorderGFX + ld hl, vTiles2 tile $6c + lb bc, BANK(EnemyHPBarBorderGFX), 4 + call Get1bpp_2 + ld de, HPExpBarBorderGFX + ld hl, vTiles2 tile $73 + lb bc, BANK(HPExpBarBorderGFX), 6 + call Get1bpp_2 + ld de, ExpBarGFX + ld hl, vTiles2 tile $55 + lb bc, BANK(ExpBarGFX), 9 + call Get2bpp_2 + ld de, MobilePhoneTilesGFX + 7 tiles ; mobile phone icon + ld hl, vTiles2 tile $5e + lb bc, BANK(MobilePhoneTilesGFX), 2 + call Get2bpp_2 + ret + +StatsScreen_LoadFont: + call _LoadFontsBattleExtra + ld de, EnemyHPBarBorderGFX + ld hl, vTiles2 tile $6c + lb bc, BANK(EnemyHPBarBorderGFX), 4 + call Get1bpp_2 + ld de, HPExpBarBorderGFX + ld hl, vTiles2 tile $78 + lb bc, BANK(HPExpBarBorderGFX), 1 + call Get1bpp_2 + ld de, HPExpBarBorderGFX + 3 * LEN_1BPP_TILE + ld hl, vTiles2 tile $76 + lb bc, BANK(HPExpBarBorderGFX), 2 + call Get1bpp_2 + ld de, ExpBarGFX + ld hl, vTiles2 tile $55 + lb bc, BANK(ExpBarGFX), 8 + call Get2bpp_2 +LoadStatsScreenPageTilesGFX: + ld de, StatsScreenPageTilesGFX + ld hl, vTiles2 tile $31 + lb bc, BANK(StatsScreenPageTilesGFX), 17 + call Get2bpp_2 + ret diff --git a/engine/gfx/load_overworld_font.asm b/engine/gfx/load_overworld_font.asm new file mode 100644 index 000000000..f4ef84619 --- /dev/null +++ b/engine/gfx/load_overworld_font.asm @@ -0,0 +1,16 @@ +LoadOverworldFont:: + ld de, .OverworldFontGFX + ld hl, vTiles1 + lb bc, BANK(.OverworldFontGFX), $80 + call Get2bpp + ld de, .OverworldFontSpaceGFX + ld hl, vTiles2 tile " " + lb bc, BANK(.OverworldFontSpaceGFX), 1 + call Get2bpp + ret + +.OverworldFontGFX: +INCBIN "gfx/font/overworld.2bpp" + +.OverworldFontSpaceGFX: +INCBIN "gfx/font/overworld_space.2bpp" diff --git a/engine/gfx/load_pics.asm b/engine/gfx/load_pics.asm new file mode 100644 index 000000000..64190083d --- /dev/null +++ b/engine/gfx/load_pics.asm @@ -0,0 +1,490 @@ +GetUnownLetter: +; Return Unown letter in wUnownLetter based on DVs at hl + +; Take the middle 2 bits of each DV and place them in order: +; atk def spd spc +; .ww..xx. .yy..zz. + + ; atk + ld a, [hl] + and %01100000 + sla a + ld b, a + ; def + ld a, [hli] + and %00000110 + swap a + srl a + or b + ld b, a + + ; spd + ld a, [hl] + and %01100000 + swap a + sla a + or b + ld b, a + ; spc + ld a, [hl] + and %00000110 + srl a + or b + +; Divide by 10 to get 0-25 + ld [hDividend + 3], a + xor a + ld [hDividend], a + ld [hDividend + 1], a + ld [hDividend + 2], a + ld a, $ff / NUM_UNOWN + 1 + ld [hDivisor], a + ld b, 4 + call Divide + +; Increment to get 1-26 + ld a, [hQuotient + 2] + inc a + ld [wUnownLetter], a + ret + +GetMonFrontpic: + ld a, [wCurPartySpecies] + ld [wCurSpecies], a + call IsAPokemon + ret c + ld a, [rSVBK] + push af + call _GetFrontpic + pop af + ld [rSVBK], a + ret + +GetAnimatedFrontpic: + ld a, [wCurPartySpecies] + ld [wCurSpecies], a + call IsAPokemon + ret c + ld a, [rSVBK] + push af + xor a + ld [hBGMapMode], a + call _GetFrontpic + call GetAnimatedEnemyFrontpic + pop af + ld [rSVBK], a + ret + +_GetFrontpic: + push de + call GetBaseData + ld a, [wBasePicSize] + and $f + ld b, a + push bc + call GetFrontpicPointer + ld a, BANK(wDecompressEnemyFrontpic) + ld [rSVBK], a + ld a, b + ld de, wDecompressEnemyFrontpic + call FarDecompress + pop bc + ld hl, wDecompressScratch + ld de, wDecompressEnemyFrontpic + call PadFrontpic + pop hl + push hl + ld de, wDecompressScratch + ld c, 7 * 7 + ld a, [hROMBank] + ld b, a + call Get2bpp + pop hl + ret + +GetFrontpicPointer: + ld a, [wCurPartySpecies] + cp UNOWN + jr z, .unown + ld a, [wCurPartySpecies] + ld d, BANK(PokemonPicPointers) + jr .ok + +.unown + ld a, [wUnownLetter] + ld d, BANK(UnownPicPointers) + +.ok + ld hl, PokemonPicPointers ; UnownPicPointers + dec a + ld bc, 6 + call AddNTimes + ld a, d + call GetFarByte + call FixPicBank + push af + inc hl + ld a, d + call GetFarHalfword + pop bc + ret + +GetAnimatedEnemyFrontpic: + ld a, BANK(vTiles3) + ld [rVBK], a + push hl + ld de, wDecompressScratch + ld c, 7 * 7 + ld a, [hROMBank] + ld b, a + call Get2bpp + pop hl + ld de, 7 * 7 tiles + add hl, de + push hl + ld a, BANK(wBasePicSize) + ld hl, wBasePicSize + call GetFarWRAMByte + pop hl + and $f + ld de, wDecompressEnemyFrontpic + 5 * 5 tiles + ld c, 5 * 5 + cp 5 + jr z, .got_dims + ld de, wDecompressEnemyFrontpic + 6 * 6 tiles + ld c, 6 * 6 + cp 6 + jr z, .got_dims + ld de, wDecompressEnemyFrontpic + 7 * 7 tiles + ld c, 7 * 7 +.got_dims + push hl + push bc + call LoadFrontpicTiles + pop bc + pop hl + ld de, wDecompressScratch + ld a, [hROMBank] + ld b, a + call Get2bpp + xor a + ld [rVBK], a + ret + +LoadFrontpicTiles: + ld hl, wDecompressScratch + swap c + ld a, c + and $f + ld b, a + ld a, c + and $f0 + ld c, a + push bc + call LoadOrientedFrontpic + pop bc +.loop + push bc + ld c, 0 + call LoadOrientedFrontpic + pop bc + dec b + jr nz, .loop + ret + +GetMonBackpic: + ld a, [wCurPartySpecies] + call IsAPokemon + ret c + + ld a, [wCurPartySpecies] + ld b, a + ld a, [wUnownLetter] + ld c, a + ld a, [rSVBK] + push af + ld a, BANK(wDecompressScratch) + ld [rSVBK], a + push de + + ; These are assumed to be at the same address in their respective banks. + ld hl, PokemonPicPointers ; UnownPicPointers + ld a, b + ld d, BANK(PokemonPicPointers) + cp UNOWN + jr nz, .ok + ld a, c + ld d, BANK(UnownPicPointers) +.ok + dec a + ld bc, 6 + call AddNTimes + ld bc, 3 + add hl, bc + ld a, d + call GetFarByte + call FixPicBank + push af + inc hl + ld a, d + call GetFarHalfword + ld de, wDecompressScratch + pop af + call FarDecompress + ld hl, wDecompressScratch + ld c, 6 * 6 + call FixBackpicAlignment + pop hl + ld de, wDecompressScratch + ld a, [hROMBank] + ld b, a + call Get2bpp + pop af + ld [rSVBK], a + ret + +FixPicBank: +; This is a thing for some reason. + +PICS_FIX EQU $36 +GLOBAL PICS_FIX + + push hl + push bc + sub BANK("Pics 1") - PICS_FIX + ld c, a + ld b, 0 + ld hl, .PicsBanks + add hl, bc + ld a, [hl] + pop bc + pop hl + ret + +.PicsBanks: + db BANK("Pics 1") ; BANK("Pics 1") + 0 + db BANK("Pics 2") ; BANK("Pics 1") + 1 + db BANK("Pics 3") ; BANK("Pics 1") + 2 + db BANK("Pics 4") ; BANK("Pics 1") + 3 + db BANK("Pics 5") ; BANK("Pics 1") + 4 + db BANK("Pics 6") ; BANK("Pics 1") + 5 + db BANK("Pics 7") ; BANK("Pics 1") + 6 + db BANK("Pics 8") ; BANK("Pics 1") + 7 + db BANK("Pics 9") ; BANK("Pics 1") + 8 + db BANK("Pics 10") ; BANK("Pics 1") + 9 + db BANK("Pics 11") ; BANK("Pics 1") + 10 + db BANK("Pics 12") ; BANK("Pics 1") + 11 + db BANK("Pics 13") ; BANK("Pics 1") + 12 + db BANK("Pics 14") ; BANK("Pics 1") + 13 + db BANK("Pics 15") ; BANK("Pics 1") + 14 + db BANK("Pics 16") ; BANK("Pics 1") + 15 + db BANK("Pics 17") ; BANK("Pics 1") + 16 + db BANK("Pics 18") ; BANK("Pics 1") + 17 + db BANK("Pics 19") ; BANK("Pics 1") + 18 + db BANK("Pics 20") ; BANK("Pics 1") + 19 + db BANK("Pics 21") ; BANK("Pics 1") + 20 + db BANK("Pics 22") ; BANK("Pics 1") + 21 + db BANK("Pics 23") ; BANK("Pics 1") + 22 + db BANK("Pics 24") ; BANK("Pics 1") + 23 + +Function511ec: + ld a, c + push de + ld hl, PokemonPicPointers + dec a + ld bc, 6 + call AddNTimes + ld a, BANK(PokemonPicPointers) + call GetFarByte + call FixPicBank + push af + inc hl + ld a, BANK(PokemonPicPointers) + call GetFarHalfword + pop af + pop de + call FarDecompress + ret + +GetTrainerPic: + ld a, [wTrainerClass] + and a + ret z + cp NUM_TRAINER_CLASSES + ret nc + call WaitBGMap + xor a + ld [hBGMapMode], a + ld hl, TrainerPicPointers + ld a, [wTrainerClass] + dec a + ld bc, 3 + call AddNTimes + ld a, [rSVBK] + push af + ld a, BANK(wDecompressScratch) + ld [rSVBK], a + push de + ld a, BANK(TrainerPicPointers) + call GetFarByte + call FixPicBank + push af + inc hl + ld a, BANK(TrainerPicPointers) + call GetFarHalfword + pop af + ld de, wDecompressScratch + call FarDecompress + pop hl + ld de, wDecompressScratch + ld c, 7 * 7 + ld a, [hROMBank] + ld b, a + call Get2bpp + pop af + ld [rSVBK], a + call WaitBGMap + ld a, $1 + ld [hBGMapMode], a + ret + +DecompressGet2bpp: +; Decompress lz data from b:hl to scratch space at 6:d000, then copy it to address de. + + ld a, [rSVBK] + push af + ld a, BANK(wDecompressScratch) + ld [rSVBK], a + + push de + push bc + ld a, b + ld de, wDecompressScratch + call FarDecompress + pop bc + ld de, wDecompressScratch + pop hl + ld a, [hROMBank] + ld b, a + call Get2bpp + + pop af + ld [rSVBK], a + ret + +FixBackpicAlignment: + push de + push bc + ld a, [wBoxAlignment] + and a + jr z, .keep_dims + ld a, c + cp 7 * 7 + ld de, 7 * 7 tiles + jr z, .got_dims + cp 6 * 6 + ld de, 6 * 6 tiles + jr z, .got_dims + ld de, 5 * 5 tiles + +.got_dims + ld a, [hl] + ld b, 0 + ld c, 8 +.loop + rra + rl b + dec c + jr nz, .loop + ld a, b + ld [hli], a + dec de + ld a, e + or d + jr nz, .got_dims + +.keep_dims + pop bc + pop de + ret + +PadFrontpic: +; pads frontpic to fill 7x7 box + ld a, b + cp 6 + jr z, .six + cp 5 + jr z, .five + +.seven_loop + ld c, 7 << 4 + call LoadOrientedFrontpic + dec b + jr nz, .seven_loop + ret + +.six + ld c, 7 << 4 + xor a + call .Fill +.six_loop + ld c, (7 - 6) << 4 + xor a + call .Fill + ld c, 6 << 4 + call LoadOrientedFrontpic + dec b + jr nz, .six_loop + ret + +.five + ld c, 7 << 4 + xor a + call .Fill +.five_loop + ld c, (7 - 5) << 4 + xor a + call .Fill + ld c, 5 << 4 + call LoadOrientedFrontpic + dec b + jr nz, .five_loop + ld c, 7 << 4 + xor a + call .Fill + ret + +.Fill: + ld [hli], a + dec c + jr nz, .Fill + ret + +LoadOrientedFrontpic: + ld a, [wBoxAlignment] + and a + jr nz, .x_flip +.left_loop + ld a, [de] + inc de + ld [hli], a + dec c + jr nz, .left_loop + ret + +.x_flip + push bc +.right_loop + ld a, [de] + inc de + ld b, a + xor a +rept 8 + rr b + rla +endr + ld [hli], a + dec c + jr nz, .right_loop + pop bc + ret diff --git a/engine/gfx/load_push_oam.asm b/engine/gfx/load_push_oam.asm new file mode 100644 index 000000000..11045bb9d --- /dev/null +++ b/engine/gfx/load_push_oam.asm @@ -0,0 +1,21 @@ +WriteOAMDMACodeToHRAM:: + ld c, hTransferVirtualOAM - $ff00 + ld b, .PushOAMEnd - .PushOAM + ld hl, .PushOAM +.loop + ld a, [hli] + ld [$ff00+c], a + inc c + dec b + jr nz, .loop + ret + +.PushOAM: + ld a, HIGH(wVirtualOAM) + ld [rDMA], a + ld a, NUM_SPRITE_OAM_STRUCTS +.pushoam_loop + dec a + jr nz, .pushoam_loop + ret +.PushOAMEnd diff --git a/engine/gfx/mon_icons.asm b/engine/gfx/mon_icons.asm new file mode 100644 index 000000000..5ae2fbf8b --- /dev/null +++ b/engine/gfx/mon_icons.asm @@ -0,0 +1,454 @@ +LoadOverworldMonIcon: + ld a, e + call ReadMonMenuIcon + ld l, a + ld h, 0 + add hl, hl + ld de, IconPointers + add hl, de + ld a, [hli] + ld e, a + ld d, [hl] + ld b, BANK(Icons) + ld c, 8 + ret + +LoadMenuMonIcon: + push hl + push de + push bc + call .LoadIcon + pop bc + pop de + pop hl + ret + +.LoadIcon: + ld d, 0 + ld hl, .Jumptable + add hl, de + add hl, de + ld a, [hli] + ld h, [hl] + ld l, a + jp hl + +.Jumptable: + dw PartyMenu_InitAnimatedMonIcon ; party menu + dw NamingScreen_InitAnimatedMonIcon ; naming screen + dw MoveList_InitAnimatedMonIcon ; moves (?) + dw Trade_LoadMonIconGFX ; trade + dw Mobile_InitAnimatedMonIcon ; mobile + dw Mobile_InitPartyMenuBGPal71 ; mobile + dw .GetPartyMenuMonIcon ; unused + +.GetPartyMenuMonIcon: + call InitPartyMenuIcon + call .GetPartyMonItemGFX + call SetPartyMonIconAnimSpeed + ret + +.GetPartyMonItemGFX: + push bc + ld a, [hObjectStructIndexBuffer] + ld hl, wPartyMon1Item + ld bc, PARTYMON_STRUCT_LENGTH + call AddNTimes + pop bc + ld a, [hl] + and a + jr z, .no_item + push hl + push bc + ld d, a + callfar ItemIsMail + pop bc + pop hl + jr c, .not_mail + ld a, $6 + jr .got_tile +.not_mail + ld a, $5 + ; jr .got_tile + +.no_item + ld a, $4 +.got_tile + ld hl, SPRITEANIMSTRUCT_FRAMESET_ID + add hl, bc + ld [hl], a + ret + +Mobile_InitAnimatedMonIcon: + call PartyMenu_InitAnimatedMonIcon + ld hl, SPRITEANIMSTRUCT_ANIM_SEQ_ID + add hl, bc + ld a, SPRITE_ANIM_SEQ_NULL + ld [hl], a + ld hl, SPRITEANIMSTRUCT_XCOORD + add hl, bc + ld a, 9 * 8 + ld [hl], a + ld hl, SPRITEANIMSTRUCT_YCOORD + add hl, bc + ld a, 9 * 8 + ld [hl], a + ret + +Mobile_InitPartyMenuBGPal71: + call InitPartyMenuIcon + call SetPartyMonIconAnimSpeed + ld hl, SPRITEANIMSTRUCT_ANIM_SEQ_ID + add hl, bc + ld a, SPRITE_ANIM_SEQ_NULL + ld [hl], a + ld hl, SPRITEANIMSTRUCT_XCOORD + add hl, bc + ld a, 3 * 8 + ld [hl], a + ld hl, SPRITEANIMSTRUCT_YCOORD + add hl, bc + ld a, 12 * 8 + ld [hl], a + ld a, c + ld [wc608], a + ld a, b + ld [wc608 + 1], a + ret + +PartyMenu_InitAnimatedMonIcon: + call InitPartyMenuIcon + call .SpawnItemIcon + call SetPartyMonIconAnimSpeed + ret + +.SpawnItemIcon: + push bc + ld a, [hObjectStructIndexBuffer] + ld hl, wPartyMon1Item + ld bc, PARTYMON_STRUCT_LENGTH + call AddNTimes + pop bc + ld a, [hl] + and a + ret z + push hl + push bc + ld d, a + callfar ItemIsMail + pop bc + pop hl + jr c, .mail + ld a, SPRITE_ANIM_FRAMESET_PARTY_MON_WITH_ITEM + jr .okay + +.mail + ld a, SPRITE_ANIM_FRAMESET_PARTY_MON_WITH_MAIL +.okay + ld hl, SPRITEANIMSTRUCT_FRAMESET_ID + add hl, bc + ld [hl], a + ret + +InitPartyMenuIcon: + ld a, [wCurIconTile] + push af + ld a, [hObjectStructIndexBuffer] + ld hl, wPartySpecies + ld e, a + ld d, $0 + add hl, de + ld a, [hl] + call ReadMonMenuIcon + ld [wCurIcon], a + call GetMemIconGFX + ld a, [hObjectStructIndexBuffer] +; y coord + add a + add a + add a + add a + add $1c + ld d, a +; x coord + ld e, $10 +; type is partymon icon + ld a, SPRITE_ANIM_INDEX_PARTY_MON + call InitSpriteAnimStruct + pop af + ld hl, SPRITEANIMSTRUCT_TILE_ID + add hl, bc + ld [hl], a + ret + +SetPartyMonIconAnimSpeed: + push bc + ld a, [hObjectStructIndexBuffer] + ld b, a + call .getspeed + ld a, b + pop bc + ld hl, SPRITEANIMSTRUCT_DURATIONOFFSET + add hl, bc + ld [hl], a + rlca + rlca + ld hl, SPRITEANIMSTRUCT_0D + add hl, bc + ld [hl], a + ret + +.getspeed + farcall PlacePartymonHPBar + call GetHPPal + ld e, d + ld d, 0 + ld hl, .speeds + add hl, de + ld b, [hl] + ret + +.speeds + db $00 ; HP_GREEN + db $40 ; HP_YELLOW + db $80 ; HP_RED + +NamingScreen_InitAnimatedMonIcon: + ld a, [wd265] + call ReadMonMenuIcon + ld [wCurIcon], a + xor a + call GetIconGFX + depixel 4, 4, 4, 0 + ld a, SPRITE_ANIM_INDEX_PARTY_MON + call InitSpriteAnimStruct + ld hl, SPRITEANIMSTRUCT_ANIM_SEQ_ID + add hl, bc + ld [hl], SPRITE_ANIM_SEQ_NULL + ret + +MoveList_InitAnimatedMonIcon: + ld a, [wd265] + call ReadMonMenuIcon + ld [wCurIcon], a + xor a + call GetIconGFX + ld d, 3 * 8 + 2 ; depixel 3, 4, 2, 4 + ld e, 4 * 8 + 4 + ld a, SPRITE_ANIM_INDEX_PARTY_MON + call InitSpriteAnimStruct + ld hl, SPRITEANIMSTRUCT_ANIM_SEQ_ID + add hl, bc + ld [hl], SPRITE_ANIM_SEQ_NULL + ret + +Trade_LoadMonIconGFX: + ld a, [wd265] + call ReadMonMenuIcon + ld [wCurIcon], a + ld a, $62 + ld [wCurIconTile], a + call GetMemIconGFX + ret + +GetSpeciesIcon: +; Load species icon into VRAM at tile a + push de + ld a, [wd265] + call ReadMonMenuIcon + ld [wCurIcon], a + pop de + ld a, e + call GetIconGFX + ret + +FlyFunction_GetMonIcon: + push de + ld a, [wd265] + call ReadMonMenuIcon + ld [wCurIcon], a + pop de + ld a, e + call GetIcon_a + ret + +Unreferenced_GetMonIcon2: + push de + ld a, [wd265] + call ReadMonMenuIcon + ld [wCurIcon], a + pop de + call GetIcon_de + ret + +GetMemIconGFX: + ld a, [wCurIconTile] +GetIconGFX: + call GetIcon_a + ld de, 8 tiles + add hl, de + ld de, HeldItemIcons + lb bc, BANK(HeldItemIcons), 2 + call GetGFXUnlessMobile + ld a, [wCurIconTile] + add 10 + ld [wCurIconTile], a + ret + +HeldItemIcons: +INCBIN "gfx/icons/mail.2bpp" +INCBIN "gfx/icons/item.2bpp" + +GetIcon_de: +; Load icon graphics into VRAM starting from tile de. + ld l, e + ld h, d + jr GetIcon + +GetIcon_a: +; Load icon graphics into VRAM starting from tile a. + ld l, a + ld h, 0 + +GetIcon: +; Load icon graphics into VRAM starting from tile hl. + +; One tile is 16 bytes long. +rept 4 + add hl, hl +endr + + ld de, vTiles0 + add hl, de + push hl + +; The icons are contiguous, in order and of the same +; size, so the pointer table is somewhat redundant. + ld a, [wCurIcon] + push hl + ld l, a + ld h, 0 + add hl, hl + ld de, IconPointers + add hl, de + ld a, [hli] + ld e, a + ld d, [hl] + pop hl + + lb bc, BANK(Icons), 8 + call GetGFXUnlessMobile + + pop hl + ret + +GetGFXUnlessMobile: + ld a, [wLinkMode] + cp LINK_MOBILE + jp nz, Request2bpp + jp Get2bpp_2 + +FreezeMonIcons: + ld hl, wSpriteAnimationStructs + ld e, PARTY_LENGTH + ld a, [wMenuCursorY] + ld d, a +.loop + ld a, [hl] + and a + jr z, .next + cp d + jr z, .loadwithtwo + ld a, SPRITE_ANIM_SEQ_NULL + jr .ok + +.loadwithtwo + ld a, SPRITE_ANIM_SEQ_PARTY_MON_SWITCH + +.ok + push hl + ld c, l + ld b, h + ld hl, SPRITEANIMSTRUCT_ANIM_SEQ_ID + add hl, bc + ld [hl], a + pop hl + +.next + ld bc, $10 + add hl, bc + dec e + jr nz, .loop + ret + +UnfreezeMonIcons: + ld hl, wSpriteAnimationStructs + ld e, PARTY_LENGTH +.loop + ld a, [hl] + and a + jr z, .next + push hl + ld c, l + ld b, h + ld hl, SPRITEANIMSTRUCT_ANIM_SEQ_ID + add hl, bc + ld [hl], SPRITE_ANIM_SEQ_PARTY_MON + pop hl +.next + ld bc, $10 + add hl, bc + dec e + jr nz, .loop + ret + +HoldSwitchmonIcon: + ld hl, wSpriteAnimationStructs + ld e, PARTY_LENGTH + ld a, [wSwitchMon] + ld d, a +.loop + ld a, [hl] + and a + jr z, .next + cp d + jr z, .is_switchmon + ld a, SPRITE_ANIM_SEQ_PARTY_MON_SELECTED + jr .join_back + +.is_switchmon + ld a, SPRITE_ANIM_SEQ_PARTY_MON_SWITCH +.join_back + push hl + ld c, l + ld b, h + ld hl, SPRITEANIMSTRUCT_ANIM_SEQ_ID + add hl, bc + ld [hl], a + pop hl +.next + ld bc, $10 + add hl, bc + dec e + jr nz, .loop + ret + +ReadMonMenuIcon: + cp EGG + jr z, .egg + dec a + ld hl, MonMenuIcons + ld e, a + ld d, 0 + add hl, de + ld a, [hl] + ret +.egg + ld a, ICON_EGG + ret + +INCLUDE "data/pokemon/menu_icons.asm" + +INCLUDE "data/icon_pointers.asm" + +INCLUDE "gfx/icons.asm" diff --git a/engine/gfx/pic_animation.asm b/engine/gfx/pic_animation.asm new file mode 100644 index 000000000..843e5cba4 --- /dev/null +++ b/engine/gfx/pic_animation.asm @@ -0,0 +1,1079 @@ +; Pic animation arrangement. + +Unused_AnimateMon_Slow_Normal: + hlcoord 12, 0 + ld a, [wBattleMode] + cp WILD_BATTLE + jr z, .wild + ld e, ANIM_MON_SLOW + ld d, $0 + call AnimateFrontpic + ret + +.wild + ld e, ANIM_MON_NORMAL + ld d, $0 + call AnimateFrontpic + ret + +AnimateMon_Menu: + ld e, ANIM_MON_MENU + ld d, $0 + call AnimateFrontpic + ret + +AnimateMon_Trade: + ld e, ANIM_MON_TRADE + ld d, $0 + call AnimateFrontpic + ret + +AnimateMon_Evolve: + ld e, ANIM_MON_EVOLVE + ld d, $0 + call AnimateFrontpic + ret + +AnimateMon_Hatch: + ld e, ANIM_MON_HATCH + ld d, $0 + call AnimateFrontpic + ret + +AnimateMon_Unused: + ld e, ANIM_MON_UNUSED + ld d, $0 + call AnimateFrontpic + ret + +pokeanim: MACRO +rept _NARG +; Workaround for a bug where macro args can't come after the start of a symbol +if !DEF(\1_POKEANIM) +\1_POKEANIM EQUS "PokeAnim_\1_" +endc + db (\1_POKEANIM - PokeAnim_SetupCommands) / 2 + shift +endr + db (PokeAnim_Finish_ - PokeAnim_SetupCommands) / 2 +ENDM + +PokeAnims: + dw .Slow + dw .Normal + dw .Menu + dw .Trade + dw .Evolve + dw .Hatch + dw .Unused ; same as .Menu + dw .Egg1 + dw .Egg2 + +.Slow: pokeanim StereoCry, Setup2, Play +.Normal: pokeanim StereoCry, Setup, Play +.Menu: pokeanim CryNoWait, Setup, Play, SetWait, Wait, Idle, Play +.Trade: pokeanim Idle, Play2, Idle, Play, SetWait, Wait, Cry, Setup, Play +.Evolve: pokeanim Idle, Play, SetWait, Wait, CryNoWait, Setup, Play +.Hatch: pokeanim Idle, Play, CryNoWait, Setup, Play, SetWait, Wait, Idle, Play +.Unused: pokeanim CryNoWait, Setup, Play, SetWait, Wait, Idle, Play +.Egg1: pokeanim Setup, Play +.Egg2: pokeanim Idle, Play + +AnimateFrontpic: + call AnimateMon_CheckIfPokemon + ret c + call LoadMonAnimation +.loop + call SetUpPokeAnim + push af + farcall HDMATransferTileMapToWRAMBank3 + pop af + jr nc, .loop + ret + +LoadMonAnimation: + push hl + ld c, e + ld b, 0 + ld hl, PokeAnims + add hl, bc + add hl, bc + ld a, [hli] + ld b, [hl] + ld c, a + pop hl + call PokeAnim_InitPicAttributes + ret + +SetUpPokeAnim: + ld a, [rSVBK] + push af + ld a, BANK(wPokeAnimSceneIndex) + ld [rSVBK], a + ld a, [wPokeAnimSceneIndex] + ld c, a + ld b, 0 + ld hl, wPokeAnimPointer + ld a, [hli] + ld h, [hl] + ld l, a + add hl, bc + ld a, [hl] + ld hl, PokeAnim_SetupCommands + rst JumpTable + ld a, [wPokeAnimSceneIndex] + ld c, a + pop af + ld [rSVBK], a + ld a, c + and $80 + ret z + scf + ret + +PokeAnim_SetupCommands: +setup_command: MACRO +\1_: dw \1 +ENDM + setup_command PokeAnim_Finish + setup_command PokeAnim_BasePic + setup_command PokeAnim_SetWait + setup_command PokeAnim_Wait + setup_command PokeAnim_Setup + setup_command PokeAnim_Setup2 + setup_command PokeAnim_Idle + setup_command PokeAnim_Play + setup_command PokeAnim_Play2 + setup_command PokeAnim_Cry + setup_command PokeAnim_CryNoWait + setup_command PokeAnim_StereoCry + +PokeAnim_SetWait: + ld a, 18 + ld [wPokeAnimWaitCounter], a + ld a, [wPokeAnimSceneIndex] + inc a + ld [wPokeAnimSceneIndex], a + +PokeAnim_Wait: + ld hl, wPokeAnimWaitCounter + dec [hl] + ret nz + ld a, [wPokeAnimSceneIndex] + inc a + ld [wPokeAnimSceneIndex], a + ret + +PokeAnim_Setup: + ld c, FALSE + ld b, 0 + call PokeAnim_InitAnim + call PokeAnim_SetVBank1 + ld a, [wPokeAnimSceneIndex] + inc a + ld [wPokeAnimSceneIndex], a + ret + +PokeAnim_Setup2: + ld c, FALSE + ld b, 4 + call PokeAnim_InitAnim + call PokeAnim_SetVBank1 + ld a, [wPokeAnimSceneIndex] + inc a + ld [wPokeAnimSceneIndex], a + ret + +PokeAnim_Idle: + ld c, TRUE + ld b, 0 + call PokeAnim_InitAnim + call PokeAnim_SetVBank1 + ld a, [wPokeAnimSceneIndex] + inc a + ld [wPokeAnimSceneIndex], a + ret + +PokeAnim_Play: + call PokeAnim_DoAnimScript + ld a, [wPokeAnimJumptableIndex] + bit 7, a + ret z + call PokeAnim_PlaceGraphic + ld a, [wPokeAnimSceneIndex] + inc a + ld [wPokeAnimSceneIndex], a + ret + +PokeAnim_Play2: + call PokeAnim_DoAnimScript + ld a, [wPokeAnimJumptableIndex] + bit 7, a + ret z + ld a, [wPokeAnimSceneIndex] + inc a + ld [wPokeAnimSceneIndex], a + ret + +PokeAnim_BasePic: + call PokeAnim_DeinitFrames + ld a, [wPokeAnimSceneIndex] + inc a + ld [wPokeAnimSceneIndex], a + ret + +PokeAnim_Finish: + call PokeAnim_DeinitFrames + ld hl, wPokeAnimSceneIndex + set 7, [hl] + ret + +PokeAnim_Cry: + ld a, [wPokeAnimSpecies] + call _PlayMonCry + ld a, [wPokeAnimSceneIndex] + inc a + ld [wPokeAnimSceneIndex], a + ret + +PokeAnim_CryNoWait: + ld a, [wPokeAnimSpecies] + call PlayMonCry2 + ld a, [wPokeAnimSceneIndex] + inc a + ld [wPokeAnimSceneIndex], a + ret + +PokeAnim_StereoCry: + ld a, $f + ld [wCryTracks], a + ld a, [wPokeAnimSpecies] + call PlayStereoCry2 + ld a, [wPokeAnimSceneIndex] + inc a + ld [wPokeAnimSceneIndex], a + ret + +PokeAnim_DeinitFrames: + ld a, [rSVBK] + push af + ld a, BANK(wPokeAnimCoord) + ld [rSVBK], a + call PokeAnim_PlaceGraphic + farcall HDMATransferTileMapToWRAMBank3 + call PokeAnim_SetVBank0 + farcall HDMATransferAttrMapToWRAMBank3 + pop af + ld [rSVBK], a + ret + +AnimateMon_CheckIfPokemon: + ld a, [wCurPartySpecies] + cp EGG + jr z, .fail + call IsAPokemon + jr c, .fail + and a + ret + +.fail + scf + ret + +PokeAnim_InitPicAttributes: + ld a, [rSVBK] + push af + ld a, BANK(wPokeAnimSceneIndex) + ld [rSVBK], a + + push bc + push de + push hl + ld hl, wPokeAnimSceneIndex + ld bc, wPokeAnimStructEnd - wPokeAnimSceneIndex + xor a + call ByteFill + pop hl + pop de + pop bc + +; bc contains anim pointer + ld a, c + ld [wPokeAnimPointer], a + ld a, b + ld [wPokeAnimPointer + 1], a +; hl contains tilemap coords + ld a, l + ld [wPokeAnimCoord], a + ld a, h + ld [wPokeAnimCoord + 1], a +; d = start tile + ld a, d + ld [wPokeAnimGraphicStartTile], a + + ld a, BANK(wCurPartySpecies) + ld hl, wCurPartySpecies + call GetFarWRAMByte + ld [wPokeAnimSpecies], a + + ld a, BANK(wUnownLetter) + ld hl, wUnownLetter + call GetFarWRAMByte + ld [wPokeAnimUnownLetter], a + + call PokeAnim_GetSpeciesOrUnown + ld [wPokeAnimSpeciesOrUnown], a + + call PokeAnim_GetFrontpicDims + ld a, c + ld [wPokeAnimFrontpicHeight], a + + pop af + ld [rSVBK], a + ret + +PokeAnim_InitAnim: + ld a, [rSVBK] + push af + ld a, BANK(wPokeAnimIdleFlag) + ld [rSVBK], a + push bc + ld hl, wPokeAnimIdleFlag + ld bc, wPokeAnimStructEnd - wPokeAnimIdleFlag + xor a + call ByteFill + pop bc + ld a, b + ld [wPokeAnimSpeed], a + ld a, c + ld [wPokeAnimIdleFlag], a + call GetMonAnimPointer + call GetMonFramesPointer + call GetMonBitmaskPointer + pop af + ld [rSVBK], a + ret + +PokeAnim_DoAnimScript: + xor a + ld [hBGMapMode], a +.loop + ld a, [wPokeAnimJumptableIndex] + and $7f + ld hl, .Jumptable + rst JumpTable + ret + +.Jumptable: + dw .RunAnim + dw .WaitAnim + +.RunAnim: + call PokeAnim_GetPointer + ld a, [wPokeAnimCommand] + cp endanim_command + jr z, PokeAnim_End + cp setrepeat_command + jr z, .SetRepeat + cp dorepeat_command + jr z, .DoRepeat + call PokeAnim_GetFrame + ld a, [wPokeAnimParameter] + call PokeAnim_GetDuration + ld [wPokeAnimWaitCounter], a + call PokeAnim_StartWaitAnim +.WaitAnim: + ld a, [wPokeAnimWaitCounter] + dec a + ld [wPokeAnimWaitCounter], a + ret nz + call PokeAnim_StopWaitAnim + ret + +.SetRepeat: + ld a, [wPokeAnimParameter] + ld [wPokeAnimRepeatTimer], a + jr .loop + +.DoRepeat: + ld a, [wPokeAnimRepeatTimer] + and a + ret z + dec a + ld [wPokeAnimRepeatTimer], a + ret z + ld a, [wPokeAnimParameter] + ld [wPokeAnimFrame], a + jr .loop + +PokeAnim_End: + ld hl, wPokeAnimJumptableIndex + set 7, [hl] + ret + +PokeAnim_GetDuration: +; a * (1 + [wPokeAnimSpeed] / 16) + ld c, a + ld b, $0 + ld hl, 0 + ld a, [wPokeAnimSpeed] + call AddNTimes + ld a, h + swap a + and $f0 + ld h, a + ld a, l + swap a + and $f + or h + add c + ret + +PokeAnim_GetFrame: + call PokeAnim_PlaceGraphic + ld a, [wPokeAnimCommand] + and a + ret z + call PokeAnim_GetBitmaskIndex + push hl + call PokeAnim_CopyBitmaskToBuffer + pop hl + call PokeAnim_ConvertAndApplyBitmask + ret + +PokeAnim_StartWaitAnim: + ld a, [wPokeAnimJumptableIndex] + inc a + ld [wPokeAnimJumptableIndex], a + ret + +PokeAnim_StopWaitAnim: + ld a, [wPokeAnimJumptableIndex] + dec a + ld [wPokeAnimJumptableIndex], a + ret + +PokeAnim_IsUnown: + ld a, [wPokeAnimSpecies] + cp UNOWN + ret + +PokeAnim_IsEgg: + ld a, [wPokeAnimSpecies] + cp EGG + ret + +PokeAnim_GetPointer: + push hl + ld a, [wPokeAnimFrame] + ld e, a + ld d, $0 + ld hl, wPokeAnimPointerAddr + ld a, [hli] + ld h, [hl] + ld l, a + add hl, de + add hl, de + ld a, [wPokeAnimPointerBank] + call GetFarHalfword + ld a, l + ld [wPokeAnimCommand], a + ld a, h + ld [wPokeAnimParameter], a + ld hl, wPokeAnimFrame + inc [hl] + pop hl + ret + +PokeAnim_GetBitmaskIndex: + ld a, [wPokeAnimCommand] + dec a + ld c, a + ld b, $0 + ld hl, wPokeAnimFramesAddr + ld a, [hli] + ld h, [hl] + ld l, a + add hl, bc + add hl, bc + ld a, [wPokeAnimFramesBank] + call GetFarHalfword + ld a, [wPokeAnimFramesBank] + call GetFarByte + ld [wPokeAnimCurBitmask], a + inc hl + ret + +PokeAnim_CopyBitmaskToBuffer: + call .GetSize + push bc + ld hl, wPokeAnimBitmaskAddr + ld a, [hli] + ld h, [hl] + ld l, a + ld a, [wPokeAnimCurBitmask] + call AddNTimes + pop bc + ld de, wPokeAnimBitmaskBuffer + ld a, [wPokeAnimBitmaskBank] + call FarCopyBytes + ret + +.GetSize: + push hl + ld a, [wPokeAnimFrontpicHeight] + sub 5 ; to get a number 0, 1, or 2 + ld c, a + ld b, 0 + ld hl, .Sizes + add hl, bc + ld c, [hl] + ld b, 0 + pop hl + ret + +.Sizes: db 4, 5, 7 + +poke_anim_box: MACRO +y = 7 +rept \1 +x = 7 + -\1 +rept \1 + db x + y +x = x + 1 +endr +y = y + 7 +endr +ENDM + +PokeAnim_ConvertAndApplyBitmask: + xor a + ld [wPokeAnimBitmaskCurBit], a + ld [wPokeAnimBitmaskCurRow], a + ld [wPokeAnimBitmaskCurCol], a +.loop + push hl + call .IsCurBitSet + pop hl + ld a, b + and a + jr z, .next + + ld a, [wPokeAnimFramesBank] + call GetFarByte + inc hl + push hl + call .ApplyFrame + pop hl + +.next + push hl + call .NextBit + pop hl + jr nc, .loop + ret + +.IsCurBitSet: +; which byte + ld a, [wPokeAnimBitmaskCurBit] + and $f8 + rrca + rrca + rrca + ld e, a + ld d, 0 + ld hl, wPokeAnimBitmaskBuffer + add hl, de + ld b, [hl] +; which bit + ld a, [wPokeAnimBitmaskCurBit] + and $7 + jr z, .skip + + ld c, a + ld a, b +.loop2 + rrca + dec c + jr nz, .loop2 + ld b, a + +.skip + xor a + bit 0, b + jr z, .finish + ld a, 1 + +.finish + ld b, a + ld hl, wPokeAnimBitmaskCurBit + inc [hl] + ret + +.ApplyFrame: + push af + call .GetCoord + pop af + push hl + call .GetTilemap + ld hl, wPokeAnimGraphicStartTile + add [hl] + pop hl + ld [hl], a + ret + +.GetCoord: + call .GetStartCoord + ld a, [wPokeAnimBitmaskCurRow] + ld bc, SCREEN_WIDTH + call AddNTimes + ld a, [wBoxAlignment] + and a + jr nz, .go + ld a, [wPokeAnimBitmaskCurCol] + ld e, a + ld d, 0 + add hl, de + jr .skip2 + +.go + ld a, [wPokeAnimBitmaskCurCol] + ld e, a + ld a, l + sub e + ld l, a + ld a, h + sbc 0 + ld h, a + +.skip2 + ret + +; unused + db 6, 5, 4 + +.GetTilemap: + push af + ld a, [wPokeAnimFrontpicHeight] + cp 5 + jr z, .check_add_24 + cp 6 + jr z, .check_add_13 + pop af + ret + +.check_add_24 + pop af + cp 5 * 5 + jr nc, .add_24 + push hl + push de + ld hl, ._5by5 + ld e, a + ld d, 0 + add hl, de + ld a, [hl] + pop de + pop hl + ret + +.add_24 + add 24 + ret + +.check_add_13 + pop af + cp 6 * 6 + jr nc, .add_13 + push hl + push de + ld hl, ._6by6 + ld e, a + ld d, 0 + add hl, de + ld a, [hl] + pop de + pop hl + ret + +.add_13 + add 13 + ret + +._5by5: + poke_anim_box 5 + ; db 9, 10, 11, 12, 13 + ; db 16, 17, 18, 19, 20 + ; db 23, 24, 25, 26, 27 + ; db 30, 31, 32, 33, 34 + ; db 37, 38, 39, 40, 41 + +._6by6: + poke_anim_box 6 + ; db 8, 9, 10, 11, 12, 13 + ; db 15, 16, 17, 18, 19, 20 + ; db 22, 23, 24, 25, 26, 27 + ; db 29, 30, 31, 32, 33, 34 + ; db 36, 37, 38, 39, 40, 41 + ; db 43, 44, 45, 46, 47, 48 + +.GetStartCoord: + ld hl, wPokeAnimCoord + ld a, [hli] + ld h, [hl] + ld l, a + + ld a, [wPokeAnimFrontpicHeight] + ld de, 0 + ld bc, 6 + cp 7 + jr z, .okay + ld de, SCREEN_WIDTH + 1 + ld bc, SCREEN_WIDTH + 5 + cp 6 + jr z, .okay + ld de, 2 * SCREEN_WIDTH + 1 + ld bc, 2 * SCREEN_WIDTH + 5 +.okay + + ld a, [wBoxAlignment] + and a + jr nz, .add_bc + add hl, de + ret + +.add_bc + add hl, bc + ret + +.NextBit: + ld a, [wPokeAnimBitmaskCurRow] + inc a + ld [wPokeAnimBitmaskCurRow], a + ld c, a + ld a, [wPokeAnimFrontpicHeight] + cp c + jr nz, .no_carry + xor a + ld [wPokeAnimBitmaskCurRow], a + ld a, [wPokeAnimBitmaskCurCol] + inc a + ld [wPokeAnimBitmaskCurCol], a + ld c, a + ld a, [wPokeAnimFrontpicHeight] + cp c + jr nz, .no_carry + scf + ret + +.no_carry + xor a + ret + +PokeAnim_PlaceGraphic: + call .ClearBox + ld a, [wBoxAlignment] + and a + jr nz, .flipped + ld de, 1 + ld bc, 0 + jr .okay + +.flipped + ld de, -1 + ld bc, 6 + +.okay + ld hl, wPokeAnimCoord + ld a, [hli] + ld h, [hl] + ld l, a + add hl, bc + ld c, 7 + ld b, 7 + ld a, [wPokeAnimGraphicStartTile] +.loop + push bc + push hl + push de + ld de, SCREEN_WIDTH +.loop2 + ld [hl], a + inc a + add hl, de + dec b + jr nz, .loop2 + pop de + pop hl + add hl, de + pop bc + dec c + jr nz, .loop + ret + +.ClearBox: + ld hl, wPokeAnimCoord + ld a, [hli] + ld h, [hl] + ld l, a + ld b, 7 + ld c, 7 + call ClearBox + ret + +PokeAnim_SetVBank1: + ld a, [rSVBK] + push af + ld a, BANK(wPokeAnimCoord) + ld [rSVBK], a + xor a + ld [hBGMapMode], a + call .SetFlag + farcall HDMATransferAttrMapToWRAMBank3 + pop af + ld [rSVBK], a + ret + +.SetFlag: + call PokeAnim_GetAttrMapCoord + ld b, 7 + ld c, 7 + ld de, SCREEN_WIDTH +.row + push bc + push hl +.col + ld a, [hl] + or 8 + ld [hl], a + add hl, de + dec c + jr nz, .col + pop hl + inc hl + pop bc + dec b + jr nz, .row + ret + +PokeAnim_SetVBank0: + call PokeAnim_GetAttrMapCoord + ld b, 7 + ld c, 7 + ld de, SCREEN_WIDTH +.row + push bc + push hl +.col + ld a, [hl] + and $f7 + ld [hl], a + add hl, de + dec c + jr nz, .col + pop hl + inc hl + pop bc + dec b + jr nz, .row + ret + +PokeAnim_GetAttrMapCoord: + ld hl, wPokeAnimCoord + ld a, [hli] + ld h, [hl] + ld l, a + ld de, wAttrMap - wTileMap + add hl, de + ret + +GetMonAnimPointer: + call PokeAnim_IsEgg + jr z, .egg + + ld c, BANK(UnownAnimations) + ld hl, UnownAnimationPointers + ld de, UnownAnimationIdlePointers + call PokeAnim_IsUnown + jr z, .unown + ld c, BANK(PicAnimations) + ld hl, AnimationPointers + ld de, AnimationIdlePointers +.unown + + ld a, [wPokeAnimIdleFlag] + and a + jr z, .idles + ld h, d + ld l, e +.idles + + ld a, [wPokeAnimSpeciesOrUnown] + dec a + ld e, a + ld d, 0 + add hl, de + add hl, de + ld a, c + ld [wPokeAnimPointerBank], a + call GetFarHalfword + ld a, l + ld [wPokeAnimPointerAddr], a + ld a, h + ld [wPokeAnimPointerAddr + 1], a + ret + +.egg + ld hl, EggAnimation + ld c, BANK(EggAnimation) + ld a, [wPokeAnimIdleFlag] + and a + jr z, .idles_egg + ld hl, EggAnimationIdle + ld c, BANK(EggAnimationIdle) +.idles_egg + + ld a, c + ld [wPokeAnimPointerBank], a + ld a, l + ld [wPokeAnimPointerAddr], a + ld a, h + ld [wPokeAnimPointerAddr + 1], a + ret + +PokeAnim_GetFrontpicDims: + ld a, [rSVBK] + push af + ld a, BANK(wCurPartySpecies) + ld [rSVBK], a + ld a, [wCurPartySpecies] + ld [wCurSpecies], a + call GetBaseData + ld a, [wBasePicSize] + and $f + ld c, a + pop af + ld [rSVBK], a + ret + +GetMonFramesPointer: + call PokeAnim_IsEgg + jr z, .egg + + call PokeAnim_IsUnown + ld b, BANK(UnownFramesPointers) + ld c, BANK(UnownsFrames) + ld hl, UnownFramesPointers + jr z, .got_frames + ld a, [wPokeAnimSpecies] + cp JOHTO_POKEMON + ld b, BANK(FramesPointers) + ld c, BANK(KantoFrames) + ld hl, FramesPointers + jr c, .got_frames + ld c, BANK(JohtoFrames) +.got_frames + ld a, c + ld [wPokeAnimFramesBank], a + + ld a, [wPokeAnimSpeciesOrUnown] + dec a + ld e, a + ld d, 0 + add hl, de + add hl, de + ld a, b + call GetFarHalfword + ld a, l + ld [wPokeAnimFramesAddr], a + ld a, h + ld [wPokeAnimFramesAddr + 1], a + ret + +.egg + ld hl, EggFrames + ld c, BANK(EggFrames) + ld a, c + ld [wPokeAnimFramesBank], a + ld a, l + ld [wPokeAnimFramesAddr], a + ld a, h + ld [wPokeAnimFramesAddr + 1], a + ret + +GetMonBitmaskPointer: + call PokeAnim_IsEgg + jr z, .egg + + call PokeAnim_IsUnown + ld a, BANK(UnownBitmasksPointers) + ld hl, UnownBitmasksPointers + jr z, .unown + ld a, BANK(BitmasksPointers) + ld hl, BitmasksPointers +.unown + ld [wPokeAnimBitmaskBank], a + + ld a, [wPokeAnimSpeciesOrUnown] + dec a + ld e, a + ld d, 0 + add hl, de + add hl, de + ld a, [wPokeAnimBitmaskBank] + call GetFarHalfword + ld a, l + ld [wPokeAnimBitmaskAddr], a + ld a, h + ld [wPokeAnimBitmaskAddr + 1], a + ret + +.egg + ld c, BANK(EggBitmasks) + ld hl, EggBitmasks + ld a, c + ld [wPokeAnimBitmaskBank], a + ld a, l + ld [wPokeAnimBitmaskAddr], a + ld a, h + ld [wPokeAnimBitmaskAddr + 1], a + ret + +PokeAnim_GetSpeciesOrUnown: + call PokeAnim_IsUnown + jr z, .unown + ld a, [wPokeAnimSpecies] + ret + +.unown + ld a, [wPokeAnimUnownLetter] + ret + +Unused_HOF_AnimateAlignedFrontpic: + ld a, $1 + ld [wBoxAlignment], a + +HOF_AnimateFrontpic: + call AnimateMon_CheckIfPokemon + jr c, .fail + ld h, d + ld l, e + push bc + push hl + ld de, vTiles2 + predef GetAnimatedFrontpic + pop hl + pop bc + ld d, 0 + ld e, c + call AnimateFrontpic + xor a + ld [wBoxAlignment], a + ret + +.fail + xor a + ld [wBoxAlignment], a + inc a + ld [wCurPartySpecies], a + ret diff --git a/engine/gfx/place_graphic.asm b/engine/gfx/place_graphic.asm new file mode 100644 index 000000000..628c72413 --- /dev/null +++ b/engine/gfx/place_graphic.asm @@ -0,0 +1,55 @@ +PlaceGraphic: +; Fill wBoxAlignment-aligned box width b height c +; with iterating tile starting from hGraphicStartTile at hl. + + ld de, SCREEN_WIDTH + + ld a, [wBoxAlignment] + and a + jr nz, .right + + ld a, [hGraphicStartTile] +.x1 + push bc + push hl + +.y1 + ld [hl], a + add hl, de + inc a + dec c + jr nz, .y1 + + pop hl + inc hl + pop bc + dec b + jr nz, .x1 + ret + +.right +; Right-aligned. + push bc + ld b, 0 + dec c + add hl, bc + pop bc + + ld a, [hGraphicStartTile] +.x2 + push bc + push hl + +.y2 + ld [hl], a + add hl, de + inc a + dec c + jr nz, .y2 + + pop hl + dec hl + pop bc + dec b + jr nz, .x2 + ret diff --git a/engine/gfx/player_gfx.asm b/engine/gfx/player_gfx.asm new file mode 100644 index 000000000..9954143a8 --- /dev/null +++ b/engine/gfx/player_gfx.asm @@ -0,0 +1,224 @@ +Unreferenced_Function88248: + ld c, CAL + ld a, [wPlayerGender] + bit PLAYERGENDER_FEMALE_F, a + jr z, .okay + ld c, KAREN + +.okay + ld a, c + ld [wTrainerClass], a + ret + +MovePlayerPicRight: + hlcoord 6, 4 + ld de, 1 + jr MovePlayerPic + +MovePlayerPicLeft: + hlcoord 13, 4 + ld de, -1 + ; fallthrough + +MovePlayerPic: +; Move player pic at hl by de * 7 tiles. + ld c, $8 +.loop + push bc + push hl + push de + xor a + ld [hBGMapMode], a + lb bc, 7, 7 + predef PlaceGraphic + xor a + ld [hBGMapThird], a + call WaitBGMap + call DelayFrame + pop de + pop hl + add hl, de + pop bc + dec c + ret z + push hl + push bc + ld a, l + sub e + ld l, a + ld a, h + sbc d + ld h, a + lb bc, 7, 7 + call ClearBox + pop bc + pop hl + jr .loop + +ShowPlayerNamingChoices: + ld hl, ChrisNameMenuHeader + ld a, [wPlayerGender] + bit PLAYERGENDER_FEMALE_F, a + jr z, .GotGender + ld hl, KrisNameMenuHeader +.GotGender: + call LoadMenuHeader + call VerticalMenu + ld a, [wMenuCursorY] + dec a + call CopyNameFromMenu + call CloseWindow + ret + +INCLUDE "data/player_names.asm" + +Unreferenced_GetPlayerNameArray: + ld hl, wPlayerName + ld de, MalePlayerNameArray + ld a, [wPlayerGender] + bit PLAYERGENDER_FEMALE_F, a + jr z, .done + ld de, FemalePlayerNameArray + +.done + call InitName + ret + +GetPlayerIcon: +; Get the player icon corresponding to gender + +; Male + ld de, ChrisSpriteGFX + ld b, BANK(ChrisSpriteGFX) + + ld a, [wPlayerGender] + bit PLAYERGENDER_FEMALE_F, a + jr z, .done + +; Female + ld de, KrisSpriteGFX + ld b, BANK(KrisSpriteGFX) + +.done + ret + +GetCardPic: + ld hl, ChrisCardPic + ld a, [wPlayerGender] + bit PLAYERGENDER_FEMALE_F, a + jr z, .GotClass + ld hl, KrisCardPic +.GotClass: + ld de, vTiles2 tile $00 + ld bc, $23 tiles + ld a, BANK(ChrisCardPic) ; BANK(KrisCardPic) + call FarCopyBytes + ld hl, CardGFX + ld de, vTiles2 tile $23 + ld bc, 6 tiles + ld a, BANK(CardGFX) + call FarCopyBytes + ret + +ChrisCardPic: +INCBIN "gfx/trainer_card/chris_card.2bpp" + +KrisCardPic: +INCBIN "gfx/trainer_card/kris_card.2bpp" + +CardGFX: +INCBIN "gfx/trainer_card/trainer_card.2bpp" + +GetPlayerBackpic: + ld a, [wPlayerGender] + bit PLAYERGENDER_FEMALE_F, a + jr z, GetChrisBackpic + call GetKrisBackpic + ret + +GetChrisBackpic: + ld hl, ChrisBackpic + ld b, BANK(ChrisBackpic) + ld de, vTiles2 tile $31 + ld c, 7 * 7 + predef DecompressGet2bpp + ret + +HOF_LoadTrainerFrontpic: + call WaitBGMap + xor a + ld [hBGMapMode], a + ld e, 0 + ld a, [wPlayerGender] + bit PLAYERGENDER_FEMALE_F, a + jr z, .GotClass + ld e, 1 + +.GotClass: + ld a, e + ld [wTrainerClass], a + ld de, ChrisPic + ld a, [wPlayerGender] + bit PLAYERGENDER_FEMALE_F, a + jr z, .GotPic + ld de, KrisPic + +.GotPic: + ld hl, vTiles2 + ld b, BANK(ChrisPic) ; BANK(KrisPic) + ld c, 7 * 7 + call Get2bpp + call WaitBGMap + ld a, $1 + ld [hBGMapMode], a + ret + +DrawIntroPlayerPic: +; Draw the player pic at (6,4). + +; Get class + ld e, CHRIS + ld a, [wPlayerGender] + bit PLAYERGENDER_FEMALE_F, a + jr z, .GotClass + ld e, KRIS +.GotClass: + ld a, e + ld [wTrainerClass], a + +; Load pic + ld de, ChrisPic + ld a, [wPlayerGender] + bit PLAYERGENDER_FEMALE_F, a + jr z, .GotPic + ld de, KrisPic +.GotPic: + ld hl, vTiles2 + ld b, BANK(ChrisPic) ; BANK(KrisPic) + ld c, 7 * 7 ; dimensions + call Get2bpp + +; Draw + xor a + ld [hGraphicStartTile], a + hlcoord 6, 4 + lb bc, 7, 7 + predef PlaceGraphic + ret + +ChrisPic: +INCBIN "gfx/player/chris.2bpp" + +KrisPic: +INCBIN "gfx/player/kris.2bpp" + +GetKrisBackpic: +; Kris's backpic is uncompressed. + ld de, KrisBackpic + ld hl, vTiles2 tile $31 + lb bc, BANK(KrisBackpic), 7 * 7 ; dimensions + call Get2bpp + ret + +KrisBackpic: +INCBIN "gfx/player/kris_back.2bpp" diff --git a/engine/gfx/sgb_layouts.asm b/engine/gfx/sgb_layouts.asm new file mode 100644 index 000000000..538132ce2 --- /dev/null +++ b/engine/gfx/sgb_layouts.asm @@ -0,0 +1,571 @@ +LoadSGBLayout: + call CheckCGB + jp nz, LoadSGBLayoutCGB + + ld a, b + cp SCGB_RAM + jr nz, .not_ram + ld a, [wSGBPredef] +.not_ram + cp SCGB_PARTY_MENU_HP_PALS + jp z, SGB_ApplyPartyMenuHPPals + ld l, a + ld h, 0 + add hl, hl + ld de, .Jumptable + add hl, de + ld a, [hli] + ld h, [hl] + ld l, a + ld de, _LoadSGBLayout_ReturnFromJumpTable + push de + jp hl + +.Jumptable: + dw .SGB_BattleGrayscale + dw .SGB_BattleColors + dw .SGB_PokegearPals + dw .SGB_StatsScreenHPPals + dw .SGB_Pokedex + dw .SGB_SlotMachine + dw .SGB06 + dw .SGB_GSIntro + dw .SGB_Diploma + dw .SGB_MapPals + dw .SGB_PartyMenu + dw .SGB_Evolution + dw .SGB_GSTitleScreen + dw .SGB0d + dw .SGB_MoveList + dw .SGB_BetaPikachuMinigame + dw .SGB_PokedexSearchOption + dw .SGB_BetaPoker + dw .SGB12 + dw .SGB13 + dw .SGB_PackPals + dw .SGB_TrainerCard + dw .SGB_PokedexUnownMode + dw .SGB_BillsPC + dw .SGB_UnownPuzzle + dw .SGB_GamefreakLogo + dw .SGB_PlayerOrMonFrontpicPals + dw .SGB_TradeTube + dw .SGB_TrainerOrMonFrontpicPals + dw .SGB_MysteryGift + dw .SGB1e + +.SGB_BattleGrayscale: + ld hl, PalPacket_BattleGrayscale + ld de, BlkPacket_Battle + ret + +.SGB_BattleColors: + ld hl, BlkPacket_Battle + call PushSGBPals_ + + ld hl, PalPacket_9ce6 + ld de, wSGBPals + ld bc, PALPACKET_LENGTH + call CopyBytes + + ld a, [wPlayerHPPal] + ld l, a + ld h, 0 + add hl, hl + add hl, hl + ld de, HPBarPals + add hl, de + + ld a, [hli] + ld [wSGBPals + 3], a + ld a, [hli] + ld [wSGBPals + 4], a + ld a, [hli] + ld [wSGBPals + 5], a + ld a, [hl] + ld [wSGBPals + 6], a + + ld a, [wEnemyHPPal] + ld l, a + ld h, 0 + add hl, hl + add hl, hl + + ld de, HPBarPals + add hl, de + ld a, [hli] + ld [wSGBPals + 9], a + ld a, [hli] + ld [wSGBPals + 10], a + ld a, [hli] + ld [wSGBPals + 11], a + ld a, [hl] + ld [wSGBPals + 12], a + + ld hl, PalPacket_9cf6 + ld de, wSGBPals + PALPACKET_LENGTH + ld bc, PALPACKET_LENGTH + call CopyBytes + + call GetBattlemonBackpicPalettePointer + + ld a, [hli] + ld [wSGBPals + 19], a + ld a, [hli] + ld [wSGBPals + 20], a + ld a, [hli] + ld [wSGBPals + 21], a + ld a, [hl] + ld [wSGBPals + 22], a + call GetEnemyFrontpicPalettePointer + ld a, [hli] + ld [wSGBPals + 25], a + ld a, [hli] + ld [wSGBPals + 26], a + ld a, [hli] + ld [wSGBPals + 27], a + ld a, [hl] + ld [wSGBPals + 28], a + + ld hl, wSGBPals + ld de, wSGBPals + PALPACKET_LENGTH + ld a, SCGB_BATTLE_COLORS + ld [wSGBPredef], a + ret + +.SGB_MoveList: + ld hl, PalPacket_9bd6 + ld de, wSGBPals + ld bc, PALPACKET_LENGTH + call CopyBytes + + ld hl, wSGBPals + 1 + ld [hl], $10 + inc hl + inc hl + + ld a, [wPlayerHPPal] + add PREDEFPAL_HP_GREEN + ld [hl], a + ld hl, wSGBPals + ld de, BlkPacket_MoveList + ret + +.SGB_PokegearPals: + ld hl, PalPacket_Pokegear + ld de, BlkPacket_9a86 + ret + +.SGB_StatsScreenHPPals: + ld hl, PalPacket_9ce6 + ld de, wSGBPals + ld bc, PALPACKET_LENGTH + call CopyBytes + ld a, [wCurHPPal] + ld l, a + ld h, 0 + add hl, hl + add hl, hl + ld de, HPBarPals + add hl, de + ld a, [hli] + ld [wSGBPals + 3], a + ld a, [hli] + ld [wSGBPals + 4], a + ld a, [hli] + ld [wSGBPals + 5], a + ld a, [hl] + ld [wSGBPals + 6], a + ld a, [wCurPartySpecies] + ld bc, wTempMonDVs + call GetPlayerOrMonPalettePointer + ld a, [hli] + ld [wSGBPals + 9], a + ld a, [hli] + ld [wSGBPals + 10], a + ld a, [hli] + ld [wSGBPals + 11], a + ld a, [hl] + ld [wSGBPals + 12], a + ld hl, wSGBPals + ld de, BlkPacket_StatsScreen + ret + +.SGB_PartyMenu: + ld hl, PalPacket_PartyMenu + ld de, wSGBPals + 1 + ret + +.SGB_Pokedex: + ld hl, PalPacket_9ce6 + ld de, wSGBPals + ld bc, PALPACKET_LENGTH + call CopyBytes + ld hl, wSGBPals + 3 + ld [hl], LOW(palred 31 + palgreen 20 + palblue 10) + inc hl + ld [hl], HIGH(palred 31 + palgreen 20 + palblue 10) + inc hl + ld [hl], LOW(palred 26 + palgreen 10 + palblue 6) + inc hl + ld [hl], HIGH(palred 26 + palgreen 10 + palblue 6) + ld a, [wCurPartySpecies] + call GetMonPalettePointer_ + ld a, [hli] + ld [wSGBPals + 9], a + ld a, [hli] + ld [wSGBPals + 10], a + ld a, [hli] + ld [wSGBPals + 11], a + ld a, [hl] + ld [wSGBPals + 12], a + ld hl, wSGBPals + ld de, BlkPacket_Pokedex_PC + ret + +.SGB_BillsPC: + ld hl, PalPacket_9ce6 + ld de, wSGBPals + ld bc, PALPACKET_LENGTH + call CopyBytes + ld hl, wSGBPals + 3 + ld [hl], LOW(palred 31 + palgreen 20 + palblue 10) + inc hl + ld [hl], HIGH(palred 31 + palgreen 20 + palblue 10) + inc hl + ld [hl], LOW(palred 26 + palgreen 10 + palblue 6) + inc hl + ld [hl], HIGH(palred 26 + palgreen 10 + palblue 6) + ld a, [wCurPartySpecies] + ld bc, wTempMonDVs + call GetPlayerOrMonPalettePointer + ld a, [hli] + ld [wSGBPals + 9], a + ld a, [hli] + ld [wSGBPals + 10], a + ld a, [hli] + ld [wSGBPals + 11], a + ld a, [hl] + ld [wSGBPals + 12], a + ld hl, wSGBPals + ld de, BlkPacket_Pokedex_PC + ret + +.SGB_PokedexUnownMode: + call .SGB_Pokedex + ld de, BlkPacket_PokedexUnownMode + ret + +.SGB_PokedexSearchOption: + ld hl, PalPacket_9ce6 + ld de, wSGBPals + ld bc, PALPACKET_LENGTH + call CopyBytes + ld hl, wSGBPals + 3 + ld [hl], LOW(palred 31 + palgreen 20 + palblue 10) + inc hl + ld [hl], HIGH(palred 31 + palgreen 20 + palblue 10) + inc hl + ld [hl], LOW(palred 26 + palgreen 10 + palblue 6) + inc hl + ld [hl], HIGH(palred 26 + palgreen 10 + palblue 6) + ld hl, wSGBPals + ld de, BlkPacket_9a86 + ret + +.SGB_PackPals: + ld hl, PalPacket_Pack + ld de, BlkPacket_9a86 + ret + +.SGB_SlotMachine: + ld hl, PalPacket_SlotMachine + ld de, BlkPacket_SlotMachine + ret + +.SGB06: + ld hl, PalPacket_SCGB_06 + ld de, BlkPacket_SCGB_06 + ret + +.SGB_Diploma: +.SGB_MysteryGift: + ld hl, PalPacket_Diploma + ld de, BlkPacket_9a86 + ret + +.SGB_GSIntro: + ld b, 0 + ld hl, .BlkPacketTable_GSIntro +rept 4 + add hl, bc +endr + ld e, [hl] + inc hl + ld d, [hl] + inc hl + ld a, [hli] + ld h, [hl] + ld l, a + ret + +.BlkPacketTable_GSIntro: + dw BlkPacket_9a86, PalPacket_GSIntroShellderLapras + dw BlkPacket_GSIntroJigglypuffPikachu, PalPacket_GSIntroJigglypuffPikachu + dw BlkPacket_9a86, PalPacket_GSIntroStartersTransition + +.SGB_GSTitleScreen: + ld hl, PalPacket_GSTitleScreen + ld de, BlkPacket_GSTitleScreen + ld a, SCGB_DIPLOMA + ld [wSGBPredef], a + ret + +.SGB13: + ld hl, PalPacket_SCGB_13 + ld de, BlkPacket_SCGB_13 + ret + +.SGB_BetaPikachuMinigame: + ld hl, PalPacket_BetaPikachuMinigame + ld de, BlkPacket_9a86 + ret + +.SGB_BetaPoker: + ld hl, BlkPacket_9a86 + ld de, wPlayerLightScreenCount ; ??? + ld bc, PALPACKET_LENGTH + call CopyBytes + ld hl, PalPacket_BetaPoker + ld de, BlkPacket_9a86 + ret + +.SGB_MapPals: + ld hl, PalPacket_9bd6 + ld de, wSGBPals + ld bc, PALPACKET_LENGTH + call CopyBytes + call .GetMapPalsIndex + ld hl, wSGBPals + 1 + ld [hld], a + ld de, BlkPacket_9a86 + ld a, SCGB_MAPPALS + ld [wSGBPredef], a + ret + +.SGB_Evolution: + push bc + ld hl, PalPacket_9ce6 + ld de, wSGBPals + ld bc, PALPACKET_LENGTH + call CopyBytes + pop bc + ld a, c + and a + jr z, .partymon + ; Egg + ld hl, wSGBPals + 3 + ld [hl], LOW(palred 7 + palgreen 7 + palblue 7) + inc hl + ld [hl], HIGH(palred 7 + palgreen 7 + palblue 7) + inc hl + ld [hl], LOW(palred 2 + palgreen 3 + palblue 3) + inc hl + ld [hl], HIGH(palred 2 + palgreen 3 + palblue 3) + jr .done + +.partymon + ld hl, wPartyMon1DVs + ld bc, PARTYMON_STRUCT_LENGTH + ld a, [wCurPartyMon] + call AddNTimes + ld c, l + ld b, h + ld a, [wPlayerHPPal] + call GetPlayerOrMonPalettePointer + ld a, [hli] + ld [wSGBPals + 3], a + ld a, [hli] + ld [wSGBPals + 4], a + ld a, [hli] + ld [wSGBPals + 5], a + ld a, [hl] + ld [wSGBPals + 6], a + +.done + ld hl, wSGBPals + ld de, BlkPacket_9a86 + ret + +.SGB0d: +.SGB_TrainerCard: + ld hl, PalPacket_Diploma + ld de, BlkPacket_9a86 + ret + +.SGB_UnownPuzzle: + ld hl, PalPacket_UnownPuzzle + ld de, BlkPacket_9a86 + ret + +.SGB12: + ld hl, PalPacket_9bd6 + ld de, wSGBPals + ld bc, PALPACKET_LENGTH + call CopyBytes + ld hl, BlkPacket_9a86 + ld de, wSGBPals + PALPACKET_LENGTH + ld bc, PALPACKET_LENGTH + call CopyBytes + call .GetMapPalsIndex + ld hl, wSGBPals + 1 + ld [hl], a + ld hl, wSGBPals + 3 + ld [hl], $2e + ld hl, wSGBPals + $13 + ld a, 5 + ld [hli], a + ld a, [wMenuBorderLeftCoord] + ld [hli], a + ld a, [wMenuBorderTopCoord] + ld [hli], a + ld a, [wMenuBorderRightCoord] + ld [hli], a + ld a, [wMenuBorderBottomCoord] + ld [hl], a + ld hl, wSGBPals + ld de, wSGBPals + PALPACKET_LENGTH + ret + +.SGB1e: + ld hl, PalPacket_9ce6 + ld de, wSGBPals + ld bc, PALPACKET_LENGTH + call CopyBytes + ld a, [wCurPartySpecies] + ld l, a + ld h, 0 + add hl, hl + add hl, hl + add hl, hl + ld de, PokemonPalettes + add hl, de + ld a, [wcf65] + and 3 + sla a + sla a + ld c, a + ld b, 0 + add hl, bc + ld a, [hli] + ld [wSGBPals + 3], a + ld a, [hli] + ld [wSGBPals + 4], a + ld a, [hli] + ld [wSGBPals + 5], a + ld a, [hl] + ld [wSGBPals + 6], a + ld hl, wSGBPals + ld de, BlkPacket_9a86 + ret + +.SGB_GamefreakLogo: + ld hl, PalPacket_GamefreakLogo + ld de, BlkPacket_9a86 + ret + +.SGB_PlayerOrMonFrontpicPals: + ld hl, PalPacket_9ce6 + ld de, wSGBPals + ld bc, PALPACKET_LENGTH + call CopyBytes + ld a, [wCurPartySpecies] + ld bc, wTempMonDVs + call GetPlayerOrMonPalettePointer + ld a, [hli] + ld [wSGBPals + 3], a + ld a, [hli] + ld [wSGBPals + 4], a + ld a, [hli] + ld [wSGBPals + 5], a + ld a, [hl] + ld [wSGBPals + 6], a + ld hl, wSGBPals + ld de, BlkPacket_9a86 + ret + +.SGB_TradeTube: + ld hl, PalPacket_TradeTube + ld de, BlkPacket_9a86 + ret + +.SGB_TrainerOrMonFrontpicPals: + ld hl, PalPacket_9ce6 + ld de, wSGBPals + ld bc, PALPACKET_LENGTH + call CopyBytes + ld a, [wCurPartySpecies] + ld bc, wTempMonDVs + call GetFrontpicPalettePointer + ld a, [hli] + ld [wSGBPals + 3], a + ld a, [hli] + ld [wSGBPals + 4], a + ld a, [hli] + ld [wSGBPals + 5], a + ld a, [hl] + ld [wSGBPals + 6], a + ld hl, wSGBPals + ld de, BlkPacket_9a86 + ret + +.GetMapPalsIndex: + ld a, [wTimeOfDayPal] + cp NITE_F + jr c, .morn_day + ld a, PREDEFPAL_NITE + ret + +.morn_day + ld a, [wEnvironment] + cp ROUTE + jr z, .route + cp CAVE + jr z, .cave + cp DUNGEON + jr z, .cave + cp ENVIRONMENT_5 + jr z, .perm5 + cp GATE + jr z, .gate + ld a, [wMapGroup] + ld e, a + ld d, 0 + ld hl, MapGroupRoofSGBPalInds + add hl, de + ld a, [hl] + ret + +.route + ld a, PREDEFPAL_00 + ret + +.cave + ld a, PREDEFPAL_DUNGEONS + ret + +.perm5 + ld a, PREDEFPAL_VERMILION + ret + +.gate + ld a, PREDEFPAL_PEWTER + ret + +INCLUDE "data/maps/sgb_roof_pal_inds.asm" + +_LoadSGBLayout_ReturnFromJumpTable: + push de + call PushSGBPals_ + pop hl + jp PushSGBPals_ diff --git a/engine/gfx/sprite_anims.asm b/engine/gfx/sprite_anims.asm new file mode 100644 index 000000000..1d3aa6a8b --- /dev/null +++ b/engine/gfx/sprite_anims.asm @@ -0,0 +1,876 @@ +DoAnimFrame: + ld hl, SPRITEANIMSTRUCT_ANIM_SEQ_ID + add hl, bc + ld e, [hl] + ld d, 0 + ld hl, .Jumptable + add hl, de + add hl, de + ld a, [hli] + ld h, [hl] + ld l, a + jp hl + +.Jumptable: +; entries correspond to SPRITE_ANIM_SEQ_* constants + dw .Null + dw .PartyMon + dw .PartyMonSwitch + dw .PartyMonSelected + dw .GSTitleTrail + dw .NamingScreenCursor + dw .GameFreakLogo + dw .GSIntroStar + dw .GSIntroSparkle + dw .SlotsGolem + dw .SlotsChansey + dw .SlotsChanseyEgg + dw .MailCursor + dw .UnusedCursor + dw .DummyGameCursor + dw .PokegearArrow + dw .TradePokeBall + dw .TradeTubeBulge + dw .TrademonInTube + dw .RevealNewMon + dw .RadioTuningKnob + dw .CutLeaves + dw .FlyFrom + dw .FlyLeaf + dw .FlyTo + dw .GSIntroHoOh + dw .EZChatCursor + dw .MobileTradeSentPulse + dw .MobileTradeOTPulse + dw .IntroSuicune + dw .IntroPichuWooper + dw .Celebi + dw .IntroUnown + dw .IntroUnownF + dw .IntroSuicuneAway + +.Null: + ret + +.PartyMon + ld a, [wMenuCursorY] + + ld hl, SPRITEANIMSTRUCT_INDEX + add hl, bc + cp [hl] + jr z, .PartyMonSwitch + + ld hl, SPRITEANIMSTRUCT_XCOORD + add hl, bc + ld [hl], 8 * 2 + + ld hl, SPRITEANIMSTRUCT_YOFFSET + add hl, bc + ld [hl], $0 + ret + +.PartyMonSwitch + ld hl, SPRITEANIMSTRUCT_XCOORD + add hl, bc + ld [hl], 8 * 3 + + ld hl, SPRITEANIMSTRUCT_0C + add hl, bc + ld a, [hl] + ld d, a + inc [hl] + and $f + ret nz + + ld hl, SPRITEANIMSTRUCT_0D + add hl, bc + ld e, [hl] + + ld hl, SPRITEANIMSTRUCT_YOFFSET + add hl, bc + ld a, d + and $10 ; bit 4 + jr z, .load_zero + ld a, e + and a + jr z, .load_minus_two + cp $1 + jr z, .load_minus_one +.load_zero + xor a + ld [hl], a + ret + +.load_minus_one + ld a, -1 + ld [hl], a + ret + +.load_minus_two + ld a, -2 + ld [hl], a + ret + +.PartyMonSelected + ld a, [wMenuCursorY] + + ld hl, SPRITEANIMSTRUCT_INDEX + add hl, bc + cp [hl] + jr z, .three_offset_right + + ld hl, SPRITEANIMSTRUCT_XCOORD + add hl, bc + ld [hl], 8 * 2 + ret + +.three_offset_right + ld hl, SPRITEANIMSTRUCT_XCOORD + add hl, bc + ld [hl], 8 * 3 + ret + +.GSTitleTrail + call .AnonymousJumptable + jp hl + +; Anonymous dw (see .AnonymousJumptable) + dw .four_zero + dw .four_one + +.four_zero + call .IncrementJumptableIndex + + ld hl, SPRITEANIMSTRUCT_INDEX + add hl, bc + ld a, [hl] + + ld hl, SPRITEANIMSTRUCT_0D + add hl, bc + and $3 + ld [hl], a + inc [hl] + swap a + + ld hl, SPRITEANIMSTRUCT_0C + add hl, bc + ld [hl], a + +.four_one + ld hl, SPRITEANIMSTRUCT_XCOORD + add hl, bc + ld a, [hl] + cp $a4 + jr nc, .asm_8d356 + + ld hl, SPRITEANIMSTRUCT_0D + add hl, bc + add $4 + + ld hl, SPRITEANIMSTRUCT_XCOORD + add hl, bc + ld [hl], a + + ld hl, SPRITEANIMSTRUCT_YCOORD + add hl, bc + inc [hl] + + ld hl, SPRITEANIMSTRUCT_0D + add hl, bc + ld a, [hl] + sla a + sla a + ld d, $2 + + ld hl, SPRITEANIMSTRUCT_0C + add hl, bc + ld a, [hl] + add $3 + ld [hl], a + call .Sprites_Sine + + ld hl, SPRITEANIMSTRUCT_YOFFSET + add hl, bc + ld [hl], a + ret + +.asm_8d356 + call DeinitializeSprite + ret + +.GSIntroHoOh + ld hl, SPRITEANIMSTRUCT_0C + add hl, bc + ld a, [hl] + inc a + ld [hl], a + ld d, $2 + call .Sprites_Sine + + ld hl, SPRITEANIMSTRUCT_YOFFSET + add hl, bc + ld [hl], a + ret + +.NamingScreenCursor + callfar NamingScreen_AnimateCursor + ret + +.MailCursor + callfar ComposeMail_AnimateCursor + ret + +.GameFreakLogo: + callfar GameFreakLogoJumper + ret + +.GSIntroStar + ld hl, SPRITEANIMSTRUCT_0C + add hl, bc + ld a, [hl] + and a + jr z, .asm_8d3ba + dec [hl] + dec [hl] + ld d, a + and $1f + jr nz, .asm_8d395 + + ld hl, SPRITEANIMSTRUCT_0D + add hl, bc + dec [hl] +.asm_8d395 + ld hl, SPRITEANIMSTRUCT_JUMPTABLE_INDEX + add hl, bc + ld a, [hl] + push af + push de + call .Sprites_Sine + + ld hl, SPRITEANIMSTRUCT_YOFFSET + add hl, bc + ld [hl], a + pop de + pop af + call .Sprites_Cosine + + ld hl, SPRITEANIMSTRUCT_XOFFSET + add hl, bc + ld [hl], a + + ld hl, SPRITEANIMSTRUCT_0D + add hl, bc + ld a, [hl] + + ld hl, SPRITEANIMSTRUCT_JUMPTABLE_INDEX + add hl, bc + add [hl] + ld [hl], a + ret + +.asm_8d3ba + ld a, $1 + ld [wcf64], a + call DeinitializeSprite + ret + +.GSIntroSparkle + ld hl, SPRITEANIMSTRUCT_0C + add hl, bc + ld a, [hli] + or [hl] + jr z, .asm_8d41e + + ld hl, SPRITEANIMSTRUCT_0F + add hl, bc + ld d, [hl] + + ld hl, SPRITEANIMSTRUCT_JUMPTABLE_INDEX + add hl, bc + ld a, [hl] + push af + push de + call .Sprites_Sine + + ld hl, SPRITEANIMSTRUCT_YOFFSET + add hl, bc + ld [hl], a + pop de + pop af + call .Sprites_Cosine + + ld hl, SPRITEANIMSTRUCT_XOFFSET + add hl, bc + ld [hl], a + + ld hl, SPRITEANIMSTRUCT_0C + add hl, bc + ld e, [hl] + inc hl + ld d, [hl] + + ld hl, SPRITEANIMSTRUCT_0E + add hl, bc + ld a, [hli] + ld h, [hl] + ld l, a + add hl, de + ld e, l + ld d, h + + ld hl, SPRITEANIMSTRUCT_0E + add hl, bc + ld [hl], e + inc hl + ld [hl], d + + ld hl, SPRITEANIMSTRUCT_0C + add hl, bc + ld a, [hli] + ld h, [hl] + ld l, a + ld de, -$10 + add hl, de + ld e, l + ld d, h + + ld hl, SPRITEANIMSTRUCT_0C + add hl, bc + ld [hl], e + inc hl + ld [hl], d + + ld hl, SPRITEANIMSTRUCT_JUMPTABLE_INDEX + add hl, bc + ld a, [hl] + xor $20 + ld [hl], a + ret + +.asm_8d41e + call DeinitializeSprite + ret + +.SlotsGolem: + callfar Slots_AnimateGolem + ret + +.SlotsChansey: + callfar Slots_AnimateChansey + ld hl, wcf64 + ld a, [hl] + cp $2 + ret nz + ld [hl], $3 + ld a, SPRITE_ANIM_FRAMESET_SLOTS_CHANSEY_2 + call _ReinitSpriteAnimFrame + ret + +.SlotsChanseyEgg: + ld hl, SPRITEANIMSTRUCT_JUMPTABLE_INDEX + add hl, bc + ld a, [hl] + dec [hl] + ld e, a + and $1 + jr z, .move_vertical + + ld hl, SPRITEANIMSTRUCT_XCOORD + add hl, bc + ld a, [hl] + cp 15 * 8 + jr c, .move_right + call DeinitializeSprite + ld a, $4 + ld [wcf64], a + ld de, SFX_PLACE_PUZZLE_PIECE_DOWN + call PlaySFX + ret + +.move_right + inc [hl] +.move_vertical + ld a, e + ld d, $20 + call .Sprites_Sine + + ld hl, SPRITEANIMSTRUCT_YOFFSET + add hl, bc + ld [hl], a + ret + +.UnusedCursor + callfar ret_e00ed + ret + +.PokegearArrow + callfar AnimatePokegearModeIndicatorArrow + ret + +.DummyGameCursor + callfar DummyGame_InterpretJoypad_AnimateCursor + ret + +.TradePokeBall + call .AnonymousJumptable + jp hl + +; Anonymous dw (see .AnonymousJumptable) + dw .TradePokeBall_zero + dw .TradePokeBall_one + dw .TradePokeBall_two + dw .TradePokeBall_three + dw .TradePokeBall_four + dw .TradePokeBall_five + +.TradePokeBall_zero + ld a, SPRITE_ANIM_FRAMESET_TRADE_POKE_BALL_WOBBLE + call _ReinitSpriteAnimFrame + + ld hl, SPRITEANIMSTRUCT_JUMPTABLE_INDEX + add hl, bc + ld [hl], $2 + + ld hl, SPRITEANIMSTRUCT_0C + add hl, bc + ld [hl], $20 + ret + +.TradePokeBall_two + ld hl, SPRITEANIMSTRUCT_0C + add hl, bc + ld a, [hl] + and a + jr z, .asm_8d4af + dec [hl] + ret + +.asm_8d4af + call .IncrementJumptableIndex + + ld hl, SPRITEANIMSTRUCT_0C + add hl, bc + ld [hl], $40 + +.TradePokeBall_three + ld hl, SPRITEANIMSTRUCT_0C + add hl, bc + ld a, [hl] + cp $30 + jr c, .asm_8d4cd + dec [hl] + ld d, $28 + call .Sprites_Sine + + ld hl, SPRITEANIMSTRUCT_YOFFSET + add hl, bc + ld [hl], a + ret + +.asm_8d4cd + ld de, SFX_GOT_SAFARI_BALLS + call PlaySFX + jr .TradePokeBall_five + +.TradePokeBall_one + ld hl, SPRITEANIMSTRUCT_JUMPTABLE_INDEX + add hl, bc + ld [hl], $4 + + ld hl, SPRITEANIMSTRUCT_0C + add hl, bc + ld [hl], $30 + + ld hl, SPRITEANIMSTRUCT_0D + add hl, bc + ld [hl], $24 + ret + +.TradePokeBall_four + ld hl, SPRITEANIMSTRUCT_0D + add hl, bc + ld a, [hl] + and a + jr z, .asm_8d51c + ld d, a + + ld hl, SPRITEANIMSTRUCT_0C + add hl, bc + ld a, [hl] + call Sprites_Sine + + ld hl, SPRITEANIMSTRUCT_YOFFSET + add hl, bc + ld [hl], a + + ld hl, SPRITEANIMSTRUCT_0C + add hl, bc + inc [hl] + ld a, [hl] + and $3f + ret nz + + ld hl, SPRITEANIMSTRUCT_0C + add hl, bc + ld [hl], $20 + + ld hl, SPRITEANIMSTRUCT_0D + add hl, bc + ld a, [hl] + sub $c + ld [hl], a + ld de, SFX_SWITCH_POKEMON + call PlaySFX + ret + +.asm_8d51c + xor a + + ld hl, SPRITEANIMSTRUCT_YOFFSET + add hl, bc + ld [hl], a + call .IncrementJumptableIndex + ret + +.TradePokeBall_five + call DeinitializeSprite + ret + +.TradeTubeBulge + ld hl, SPRITEANIMSTRUCT_XCOORD + add hl, bc + ld a, [hl] + inc [hl] + inc [hl] + cp $b0 + jr nc, .delete + and $3 + ret nz + ld de, SFX_POKEBALLS_PLACED_ON_TABLE + call PlaySFX + ret + +.delete + call DeinitializeSprite + ret + +.TrademonInTube + callfar TradeAnim_AnimateTrademonInTube + ret + +.RevealNewMon: + ld hl, SPRITEANIMSTRUCT_0C + add hl, bc + ld a, [hl] + cp $80 + jr nc, .finish_EggShell + ld d, a + add $8 + ld [hl], a + + ld hl, SPRITEANIMSTRUCT_JUMPTABLE_INDEX + add hl, bc + ld a, [hl] + xor $20 + ld [hl], a + + push af + push de + call .Sprites_Sine + + ld hl, SPRITEANIMSTRUCT_YOFFSET + add hl, bc + ld [hl], a + + pop de + pop af + call .Sprites_Cosine + + ld hl, SPRITEANIMSTRUCT_XOFFSET + add hl, bc + ld [hl], a + ret + +.finish_EggShell + call DeinitializeSprite + ret + +.RadioTuningKnob: + callfar AnimateTuningKnob + ret + +.CutLeaves + ld hl, SPRITEANIMSTRUCT_0D + add hl, bc + ld e, [hl] + inc hl + ld d, [hl] + ld hl, $80 + add hl, de + ld e, l + ld d, h + + ld hl, SPRITEANIMSTRUCT_0D + add hl, bc + ld [hl], e + inc hl + ld [hl], d + + ld hl, SPRITEANIMSTRUCT_0C + add hl, bc + ld a, [hl] + inc [hl] + inc [hl] + inc [hl] + push af + push de + call .Sprites_Sine + + ld hl, SPRITEANIMSTRUCT_YOFFSET + add hl, bc + ld [hl], a + pop de + pop af + call .Sprites_Cosine + + ld hl, SPRITEANIMSTRUCT_XOFFSET + add hl, bc + ld [hl], a + ret + +.FlyFrom: + ld hl, SPRITEANIMSTRUCT_YCOORD + add hl, bc + ld a, [hl] + and a + ret z + + ld hl, SPRITEANIMSTRUCT_0D + add hl, bc + ld a, [hl] + inc [hl] + cp $40 + ret c + + ld hl, SPRITEANIMSTRUCT_YCOORD + add hl, bc + dec [hl] + dec [hl] + + ld hl, SPRITEANIMSTRUCT_0F + add hl, bc + ld a, [hl] + ld d, a + cp $40 + jr nc, .skip + add $8 + ld [hl], a +.skip + ld hl, SPRITEANIMSTRUCT_0E + add hl, bc + ld a, [hl] + inc [hl] + call .Sprites_Cosine + + ld hl, SPRITEANIMSTRUCT_XOFFSET + add hl, bc + ld [hl], a + ret + +.FlyLeaf: + ld hl, SPRITEANIMSTRUCT_XCOORD + add hl, bc + ld a, [hl] + cp -9 * 8 + jr nc, .delete_leaf + inc [hl] + inc [hl] + + ld hl, SPRITEANIMSTRUCT_YCOORD + add hl, bc + dec [hl] + + ld d, $40 + ld hl, SPRITEANIMSTRUCT_0C + add hl, bc + ld a, [hl] + inc [hl] + call .Sprites_Cosine + + ld hl, SPRITEANIMSTRUCT_XOFFSET + add hl, bc + ld [hl], a + ret + +.delete_leaf + call DeinitializeSprite + ret + +.FlyTo: + ld hl, SPRITEANIMSTRUCT_YCOORD + add hl, bc + ld a, [hl] + cp 10 * 8 + 4 + ret z + + ld hl, SPRITEANIMSTRUCT_YCOORD + add hl, bc + inc [hl] + inc [hl] + + ld hl, SPRITEANIMSTRUCT_0F + add hl, bc + ld a, [hl] + ld d, a + and a + jr z, .asm_8d621 + sub $2 + ld [hl], a +.asm_8d621 + ld hl, SPRITEANIMSTRUCT_0E + add hl, bc + ld a, [hl] + inc [hl] + call .Sprites_Cosine + + ld hl, SPRITEANIMSTRUCT_XOFFSET + add hl, bc + ld [hl], a + ret + +.MobileTradeSentPulse + farcall Function108bc7 + ret + +.MobileTradeOTPulse + farcall Function108be0 + ret + +.IntroSuicune + ld a, [wcf65] + and a + jr nz, .asm_8d645 + ret +.asm_8d645 + ld hl, SPRITEANIMSTRUCT_YOFFSET + add hl, bc + ld [hl], $0 + + ld hl, SPRITEANIMSTRUCT_0D + add hl, bc + ld a, [hl] + add $2 + ld [hl], a + xor $ff + inc a + ld d, $20 + call .Sprites_Sine + + ld hl, SPRITEANIMSTRUCT_YOFFSET + add hl, bc + ld [hl], a + ld a, SPRITE_ANIM_FRAMESET_INTRO_SUICUNE_2 + call _ReinitSpriteAnimFrame + ret + +.IntroPichuWooper + ld hl, SPRITEANIMSTRUCT_0C + add hl, bc + ld a, [hl] + cp $14 + jr nc, .asm_8d67f + add $2 + ld [hl], a + xor $ff + inc a + ld d, $20 + call .Sprites_Sine + + ld hl, SPRITEANIMSTRUCT_YOFFSET + add hl, bc + ld [hl], a +.asm_8d67f + ret + +.IntroUnown + ld hl, SPRITEANIMSTRUCT_JUMPTABLE_INDEX + add hl, bc + ld d, [hl] + inc [hl] + inc [hl] + inc [hl] + + ld hl, SPRITEANIMSTRUCT_0C + add hl, bc + ld a, [hl] + push af + push de + call .Sprites_Sine + + ld hl, SPRITEANIMSTRUCT_YOFFSET + add hl, bc + ld [hl], a + pop de + pop af + call .Sprites_Cosine + + ld hl, SPRITEANIMSTRUCT_XOFFSET + add hl, bc + ld [hl], a + ret + +.IntroUnownF + ld a, [wcf64] + cp $40 + ret nz + ld a, SPRITE_ANIM_FRAMESET_INTRO_UNOWN_F_2 + call _ReinitSpriteAnimFrame + ret + +.IntroSuicuneAway + ld hl, SPRITEANIMSTRUCT_YCOORD + add hl, bc + ld a, [hl] + add $10 + ld [hl], a + ret + +.EZChatCursor + farcall AnimateEZChatCursor + ret + +.Celebi + farcall UpdateCelebiPosition + ret + +.AnonymousJumptable: + ld hl, sp+$0 + ld e, [hl] + inc hl + ld d, [hl] + inc de + + ld hl, SPRITEANIMSTRUCT_JUMPTABLE_INDEX + add hl, bc + ld l, [hl] + ld h, $0 + add hl, hl + add hl, de + ld a, [hli] + ld h, [hl] + ld l, a + ret + +.IncrementJumptableIndex: + ld hl, SPRITEANIMSTRUCT_JUMPTABLE_INDEX + add hl, bc + inc [hl] + ret + +.Sprites_Sine: + call Sprites_Sine + ret + +.Sprites_Cosine: + call Sprites_Cosine + ret diff --git a/engine/gfx/sprites.asm b/engine/gfx/sprites.asm new file mode 100644 index 000000000..1b22e5832 --- /dev/null +++ b/engine/gfx/sprites.asm @@ -0,0 +1,649 @@ +ClearSpriteAnims: + ld hl, wSpriteAnimDict + ld bc, wSpriteAnimsEnd - wSpriteAnimDict +.loop + ld [hl], $0 + inc hl + dec bc + ld a, c + or b + jr nz, .loop + ret + +PlaySpriteAnimationsAndDelayFrame: + call PlaySpriteAnimations + call DelayFrame + ret + +PlaySpriteAnimations: + push hl + push de + push bc + push af + + ld a, LOW(wVirtualOAM) + ld [wCurrSpriteOAMAddr], a + call DoNextFrameForAllSprites + + pop af + pop bc + pop de + pop hl + ret + +DoNextFrameForAllSprites: + ld hl, wSpriteAnimationStructs + ld e, NUM_SPRITE_ANIM_STRUCTS + +.loop + ld a, [hl] + and a + jr z, .next ; This struct is deinitialized. + ld c, l + ld b, h + push hl + push de + call DoAnimFrame ; Uses a massive dw + call UpdateAnimFrame + pop de + pop hl + jr c, .done + +.next + ld bc, SPRITEANIMSTRUCT_LENGTH + add hl, bc + dec e + jr nz, .loop + + ld a, [wCurrSpriteOAMAddr] + ld l, a + ld h, HIGH(wVirtualOAM) + +.loop2 ; Clear (wVirtualOAM + [wCurrSpriteOAMAddr] --> wVirtualOAMEnd) + ld a, l + cp LOW(wVirtualOAMEnd) + jr nc, .done + xor a + ld [hli], a + jr .loop2 + +.done + ret + +DoNextFrameForFirst16Sprites: + ld hl, wSpriteAnimationStructs + ld e, NUM_SPRITE_ANIM_STRUCTS + +.loop + ld a, [hl] + and a + jr z, .next + ld c, l + ld b, h + push hl + push de + call DoAnimFrame ; Uses a massive dw + call UpdateAnimFrame + pop de + pop hl + jr c, .done + +.next + ld bc, SPRITEANIMSTRUCT_LENGTH + add hl, bc + dec e + jr nz, .loop + + ld a, [wCurrSpriteOAMAddr] + ld l, a + ld h, HIGH(wVirtualOAMSprite16) + +.loop2 ; Clear (wVirtualOAM + [wCurrSpriteOAMAddr] --> Sprites + $40) + ld a, l + cp LOW(wVirtualOAMSprite16) + jr nc, .done + xor a + ld [hli], a + jr .loop2 + +.done + ret + +InitSpriteAnimStruct:: +; Initialize animation a at pixel x=e, y=d +; Find if there's any room in the wSpriteAnimationStructs array, which is 10x16 + push de + push af + ld hl, wSpriteAnimationStructs + ld e, NUM_SPRITE_ANIM_STRUCTS +.loop + ld a, [hl] + and a + jr z, .found + ld bc, SPRITEANIMSTRUCT_LENGTH + add hl, bc + dec e + jr nz, .loop +; We've reached the end. There is no more room here. +; Return carry. + pop af + pop de + scf + ret + +.found +; Back up the structure address to bc. + ld c, l + ld b, h +; Value [wSpriteAnimCount] is initially set to -1. Set it to +; the number of objects loaded into this array. + ld hl, wSpriteAnimCount + inc [hl] + ld a, [hl] + and a + jr nz, .initialized + inc [hl] + +.initialized +; Get row a of SpriteAnimSeqData, copy the pointer into de + pop af + ld e, a + ld d, 0 + ld hl, SpriteAnimSeqData + add hl, de + add hl, de + add hl, de + ld e, l + ld d, h +; Set hl to the first field (field 0) in the current structure. + ld hl, SPRITEANIMSTRUCT_INDEX + add hl, bc +; Load the index. + ld a, [wSpriteAnimCount] + ld [hli], a +; Copy the table entry to the next two fields. + ld a, [de] + ld [hli], a + inc de + ld a, [de] + ld [hli], a + inc de +; Look up the third field from the table in the wSpriteAnimDict array (10x2). +; Take the value and load it in + ld a, [de] + call GetSpriteAnimVTile + ld [hli], a + pop de +; Set hl to field 4 (X coordinate). Kinda pointless, because we're presumably already here. + ld hl, SPRITEANIMSTRUCT_XCOORD + add hl, bc +; Load the original value of de into here. + ld a, e + ld [hli], a + ld a, d + ld [hli], a +; load 0 into the next four fields + xor a + ld [hli], a + ld [hli], a + xor a + ld [hli], a + ld [hli], a +; load -1 into the next field + dec a + ld [hli], a +; load 0 into the last five fields + xor a +rept 4 + ld [hli], a +endr + ld [hl], a +; back up the address of the first field to wSpriteAnimAddrBackup + ld a, c + ld [wSpriteAnimAddrBackup], a + ld a, b + ld [wSpriteAnimAddrBackup + 1], a + ret + +DeinitializeSprite: +; Clear the index field of the struct in bc. + ld hl, SPRITEANIMSTRUCT_INDEX + add hl, bc + ld [hl], $0 + ret + +DeinitializeAllSprites: +; Clear the index field of every struct in the wSpriteAnimationStructs array. + ld hl, wSpriteAnimationStructs + ld bc, SPRITEANIMSTRUCT_LENGTH + ld e, NUM_SPRITE_ANIM_STRUCTS + xor a +.loop + ld [hl], a + add hl, bc + dec e + jr nz, .loop + ret + +UpdateAnimFrame: + call InitSpriteAnimBuffer ; init WRAM + call GetSpriteAnimFrame ; read from a memory array + cp -3 + jr z, .done + cp -4 + jr z, .delete + call GetFrameOAMPointer + ; add byte to [wCurrAnimVTile] + ld a, [wCurrAnimVTile] + add [hl] + ld [wCurrAnimVTile], a + inc hl + ; load pointer into hl + ld a, [hli] + ld h, [hl] + ld l, a + push bc + ld a, [wCurrSpriteOAMAddr] + ld e, a + ld d, HIGH(wVirtualOAM) + ld a, [hli] + ld c, a ; number of objects +.loop + ; first byte: y (px) + ; [de] = [wCurrAnimYCoord] + [wCurrAnimYOffset] + [wGlobalAnimYOffset] + AddOrSubtractY([hl]) + ld a, [wCurrAnimYCoord] + ld b, a + ld a, [wCurrAnimYOffset] + add b + ld b, a + ld a, [wGlobalAnimYOffset] + add b + ld b, a + call AddOrSubtractY + add b + ld [de], a + inc hl + inc de + ; second byte: x (px) + ; [de] = [wCurrAnimXCoord] + [wCurrAnimXOffset] + [wGlobalAnimXOffset] + AddOrSubtractX([hl]) + ld a, [wCurrAnimXCoord] + ld b, a + ld a, [wCurrAnimXOffset] + add b + ld b, a + ld a, [wGlobalAnimXOffset] + add b + ld b, a + call AddOrSubtractX + add b + ld [de], a + inc hl + inc de + ; third byte: vtile + ; [de] = [wCurrAnimVTile] + [hl] + ld a, [wCurrAnimVTile] + add [hl] + ld [de], a + inc hl + inc de + ; fourth byte: attributes + ; [de] = GetSpriteOAMAttr([hl]) + call GetSpriteOAMAttr + ld [de], a + inc hl + inc de + ld a, e + ld [wCurrSpriteOAMAddr], a + cp LOW(wVirtualOAMEnd) + jr nc, .reached_the_end + dec c + jr nz, .loop + pop bc + jr .done + +.delete + call DeinitializeSprite +.done + and a + ret + +.reached_the_end + pop bc + scf + ret + +AddOrSubtractY: + push hl + ld a, [hl] + ld hl, wCurrSpriteAddSubFlags + bit 6, [hl] + jr z, .ok + ; 8 - a + add $8 + xor $ff + inc a + +.ok + pop hl + ret + +AddOrSubtractX: + push hl + ld a, [hl] + ld hl, wCurrSpriteAddSubFlags + bit 5, [hl] ; x flip + jr z, .ok + ; 8 - a + add $8 + xor $ff + inc a + +.ok + pop hl + ret + +GetSpriteOAMAttr: + ld a, [wCurrSpriteAddSubFlags] + ld b, a + ld a, [hl] + xor b + and $e0 + ld b, a + ld a, [hl] + and $1f + or b + ret + +InitSpriteAnimBuffer: + xor a + ld [wCurrSpriteAddSubFlags], a + ld hl, SPRITEANIMSTRUCT_TILE_ID + add hl, bc + ld a, [hli] + ld [wCurrAnimVTile], a + ld a, [hli] + ld [wCurrAnimXCoord], a + ld a, [hli] + ld [wCurrAnimYCoord], a + ld a, [hli] + ld [wCurrAnimXOffset], a + ld a, [hli] + ld [wCurrAnimYOffset], a + ret + +GetSpriteAnimVTile: +; a = wSpriteAnimDict[a] if a in wSpriteAnimDict else 0 +; vTiles offset + push hl + push bc + ld hl, wSpriteAnimDict + ld b, a + ld c, NUM_SPRITE_ANIM_STRUCTS +.loop + ld a, [hli] + cp b + jr z, .ok + inc hl + dec c + jr nz, .loop + xor a + jr .done + +.ok + ld a, [hl] + +.done + pop bc + pop hl + ret + +_ReinitSpriteAnimFrame:: + ld hl, SPRITEANIMSTRUCT_FRAMESET_ID + add hl, bc + ld [hl], a + ld hl, SPRITEANIMSTRUCT_DURATION + add hl, bc + ld [hl], 0 + ld hl, SPRITEANIMSTRUCT_FRAME + add hl, bc + ld [hl], -1 + ret + +GetSpriteAnimFrame: +.loop + ld hl, SPRITEANIMSTRUCT_DURATION + add hl, bc + ld a, [hl] + and a + jr z, .next_frame ; finished the current sequence + dec [hl] + call .GetPointer ; load pointer from SpriteAnimFrameData + ld a, [hli] + push af + jr .okay + +.next_frame + ld hl, SPRITEANIMSTRUCT_FRAME + add hl, bc + inc [hl] + call .GetPointer ; load pointer from SpriteAnimFrameData + ld a, [hli] + cp dorestart_command + jr z, .restart + cp endanim_command + jr z, .repeat_last + + push af + ld a, [hl] + push hl + and $3f + ld hl, SPRITEANIMSTRUCT_DURATIONOFFSET + add hl, bc + add [hl] + ld hl, SPRITEANIMSTRUCT_DURATION + add hl, bc + ld [hl], a + pop hl +.okay + ld a, [hl] + and $c0 + srl a + ld [wCurrSpriteAddSubFlags], a + pop af + ret + +.repeat_last + xor a + ld hl, SPRITEANIMSTRUCT_DURATION + add hl, bc + ld [hl], a + + ld hl, SPRITEANIMSTRUCT_FRAME + add hl, bc + dec [hl] + dec [hl] + jr .loop + +.restart + xor a + ld hl, SPRITEANIMSTRUCT_DURATION + add hl, bc + ld [hl], a + + dec a + ld hl, SPRITEANIMSTRUCT_FRAME + add hl, bc + ld [hl], a + jr .loop + +.GetPointer: + ; Get the data for the current frame for the current animation sequence + + ; SpriteAnimFrameData[SpriteAnim[SPRITEANIMSTRUCT_FRAMESET_ID]][SpriteAnim[SPRITEANIMSTRUCT_FRAME]] + ld hl, SPRITEANIMSTRUCT_FRAMESET_ID + add hl, bc + ld e, [hl] + ld d, 0 + ld hl, SpriteAnimFrameData + add hl, de + add hl, de + ld e, [hl] + inc hl + ld d, [hl] + ld hl, SPRITEANIMSTRUCT_FRAME + add hl, bc + ld l, [hl] + ld h, 0 + add hl, hl + add hl, de + ret + +GetFrameOAMPointer: +; Load OAM data pointer + ld e, a + ld d, 0 + ld hl, SpriteAnimOAMData + add hl, de + add hl, de + add hl, de + ret + +Unreferenced_BrokenGetStdGraphics: + push hl + ld l, a + ld h, 0 + add hl, hl + add hl, hl + ld de, BrokenStdGFXPointers ; broken 2bpp pointers + add hl, de + ld c, [hl] + inc hl + ld b, [hl] + inc hl + ld e, [hl] + inc hl + ld d, [hl] + pop hl + push bc + call Request2bpp + pop bc + ret + +INCLUDE "data/sprite_anims/sequences.asm" + +INCLUDE "engine/gfx/sprite_anims.asm" + +INCLUDE "data/sprite_anims/framesets.asm" + +INCLUDE "data/sprite_anims/oam.asm" + +BrokenStdGFXPointers: + ; tile count, bank, pointer + ; (all pointers were dummied out to .deleted) + dbbw 128, $01, .deleted + dbbw 128, $01, .deleted + dbbw 128, $01, .deleted + dbbw 128, $01, .deleted + dbbw 16, $37, .deleted + dbbw 16, $11, .deleted + dbbw 16, $39, .deleted + dbbw 16, $24, .deleted + dbbw 16, $21, .deleted + +.deleted + +Sprites_Cosine: +; a = d * cos(a * pi/32) + add %010000 ; cos(x) = sin(x + pi/2) + ; fallthrough +Sprites_Sine: +; a = d * sin(a * pi/32) + calc_sine_wave + +AnimateEndOfExpBar: + ld a, [hSGB] + ld de, EndOfExpBarGFX + and a + jr z, .load + ld de, SGBEndOfExpBarGFX + +.load + ld hl, vTiles0 tile $00 + lb bc, BANK(EndOfExpBarGFX), 1 + call Request2bpp + ld c, 8 + ld d, 0 +.loop + push bc + call .AnimateFrame + call DelayFrame + pop bc + inc d + inc d + dec c + jr nz, .loop + call ClearSprites + ret + +.AnimateFrame: + ld hl, wVirtualOAMSprite00 + ld c, 8 ; number of animated circles +.anim_loop + ld a, c + and a + ret z + dec c + ld a, c +; multiply by 8 + sla a + sla a + sla a + push af + + push de + push hl + call Sprites_Sine + pop hl + pop de + add 13 * TILE_WIDTH + ld [hli], a ; y + + pop af + push de + push hl + call Sprites_Cosine + pop hl + pop de + add 10 * TILE_WIDTH + 4 + ld [hli], a ; x + + ld a, $0 + ld [hli], a ; tile id + ld a, PAL_BATTLE_OB_BLUE + ld [hli], a ; attributes + jr .anim_loop + +EndOfExpBarGFX: +INCBIN "gfx/battle/expbarend.2bpp" +SGBEndOfExpBarGFX: +INCBIN "gfx/battle/expbarend_sgb.2bpp" + +ClearSpriteAnims2: + push hl + push de + push bc + push af + ld hl, wSpriteAnimDict + ld bc, wSpriteAnimsEnd - wSpriteAnimDict +.loop + ld [hl], 0 + inc hl + dec bc + ld a, c + or b + jr nz, .loop + pop af + pop bc + pop de + pop hl + ret diff --git a/engine/gfx/trademon_frontpic.asm b/engine/gfx/trademon_frontpic.asm new file mode 100644 index 000000000..d557123e9 --- /dev/null +++ b/engine/gfx/trademon_frontpic.asm @@ -0,0 +1,38 @@ +GetTrademonFrontpic: + ld a, [wOTTrademonSpecies] + ld hl, wOTTrademonDVs + ld de, vTiles2 + push de + push af + predef GetUnownLetter + pop af + ld [wCurPartySpecies], a + ld [wCurSpecies], a + call GetBaseData + pop de + predef GetAnimatedFrontpic + ret + +AnimateTrademonFrontpic: + ld a, [wOTTrademonSpecies] + call IsAPokemon + ret c + farcall ShowOTTrademonStats + ld a, [wOTTrademonSpecies] + ld [wCurPartySpecies], a + ld a, [wOTTrademonDVs] + ld [wTempMonDVs], a + ld a, [wOTTrademonDVs + 1] + ld [wTempMonDVs + 1], a + ld b, SCGB_PLAYER_OR_MON_FRONTPIC_PALS + call GetSGBLayout + ld a, %11100100 ; 3,2,1,0 + call DmgToCgbBGPals + farcall TradeAnim_ShowGetmonFrontpic + ld a, [wOTTrademonSpecies] + ld [wCurPartySpecies], a + hlcoord 7, 2 + ld d, $0 + ld e, ANIM_MON_TRADE + predef AnimateFrontpic + ret |