ref: 82aea0f71eba0b93dc3d19ad31e024fcbbff8c20
dir: /engine/gfx/pic_animation.asm/
; 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_HOF: ld e, ANIM_MON_HOF 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: ; entries correspond to ANIM_MON_* constants dw .Slow dw .Normal dw .Menu dw .Trade dw .Evolve dw .Hatch dw .HOF 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 .HOF: 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: ldh a, [rSVBK] push af ld a, BANK(wPokeAnimStruct) ldh [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 ldh [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: ldh a, [rSVBK] push af ld a, BANK(wPokeAnimCoord) ldh [rSVBK], a call PokeAnim_PlaceGraphic farcall HDMATransferTileMapToWRAMBank3 call PokeAnim_SetVBank0 farcall HDMATransferAttrMapToWRAMBank3 pop af ldh [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: ldh a, [rSVBK] push af ld a, BANK(wPokeAnimStruct) ldh [rSVBK], a push bc push de push hl ld hl, wPokeAnimStruct ld bc, wPokeAnimStructEnd - wPokeAnimStruct 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 ldh [rSVBK], a ret PokeAnim_InitAnim: ldh a, [rSVBK] push af ld a, BANK(wPokeAnimIdleFlag) ldh [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 ldh [rSVBK], a ret PokeAnim_DoAnimScript: xor a ldh [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: ldh a, [rSVBK] push af ld a, BANK(wPokeAnimCoord) ldh [rSVBK], a xor a ldh [hBGMapMode], a call .SetFlag farcall HDMATransferAttrMapToWRAMBank3 pop af ldh [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(UnownAnimationPointers) ; aka BANK(UnownAnimationIdlePointers) ld hl, UnownAnimationPointers ld de, UnownAnimationIdlePointers call PokeAnim_IsUnown jr z, .unown ld c, BANK(AnimationPointers) ; aka BANK(AnimationIdlePointers) 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: ldh a, [rSVBK] push af ld a, BANK(wCurPartySpecies) ldh [rSVBK], a ld a, [wCurPartySpecies] ld [wCurSpecies], a call GetBaseData ld a, [wBasePicSize] and $f ld c, a pop af ldh [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