shithub: pokered

Download patch

ref: 3cf0197493c2e30a109a8aabc171fa62e3891fcc
parent: 2e67759f9daf0d833d21bac3aea38444d0578974
author: YamaArashi <shadow962@live.com>
date: Wed Feb 1 16:47:44 EST 2012

disasm of more battle animation code

hg-commit-id: ddca5fa6dbad


--- a/constants.asm
+++ b/constants.asm
@@ -281,7 +281,7 @@
 
 W_SUBANIMFRAMEDELAY EQU $D086 ; duration of each frame of the current subanimation in terms of screen refreshes
 
-W_SUBANIMSIZE EQU $D087 ; number of frame blocks in the current subanimation
+W_SUBANIMCOUNTER EQU $D087 ; counts the number of subentries left in the current subanimation
 
 W_NUMFBTILES EQU $D089 ; number of tiles in current battle animation frame block
 
@@ -1618,6 +1618,7 @@
 SLP_ANIM     EQU $BD ; sleeping monster
 CONF_ANIM    EQU $BF ; confused monster
 TOSS_ANIM    EQU $C1 ; toss Poké Ball
+SHAKE_ANIM   EQU $C2 ; shaking Poké Ball when catching monster
 POOF_ANIM    EQU $C3 ; puff of smoke
 BLOCKBALL_ANIM EQU $C4 ; trainer knocks away Poké Ball
 GREATTOSS_ANIM EQU $C5 ; toss Great Ball
--- a/main.asm
+++ b/main.asm
@@ -12952,8 +12952,8 @@
 .BallSuccess2\@	;$5805
 	ld c,20
 	call DelayFrames
-	ld a,$c1
-	ld [$d07c],a
+	ld a,TOSS_ANIM
+	ld [W_ANIMATIONID],a
 	xor a
 	ld [$fff3],a
 	ld [$cc5b],a
@@ -63972,7 +63972,7 @@
 	ld a,[hli]
 	cp a,$FF ; is there a sound to play?
 	jr z,.skipPlayingSound\@
-	ld [$CF07],a ; store sound
+	ld [W_ANIMSOUNDID],a ; store sound
 	push hl
 	push de
 	call $586F
@@ -64001,7 +64001,7 @@
 	rla
 	ld [$D09F],a ; tile select
 	ld a,[hli] ; sound
-	ld [$CF07],a ; store sound
+	ld [W_ANIMSOUNDID],a ; store sound
 	ld a,[hli] ; subanimation ID
 	ld c,l
 	ld b,h
@@ -64044,7 +64044,7 @@
 	ld a,[de]
 	ld b,a
 	and a,31
-	ld [W_SUBANIMSIZE],a ; number of frame blocks
+	ld [W_SUBANIMCOUNTER],a ; number of frame blocks
 	ld a,b
 	and a,%11100000
 	cp a,5 << 5 ; is subanimation type 5?
@@ -64063,7 +64063,7 @@
 	ld hl,0
 	jr nz,.storeSubentryAddr\@
 ; if the animation is reversed, then place the initial subentry address at the end of the list of subentries
-	ld a,[W_SUBANIMSIZE]
+	ld a,[W_SUBANIMCOUNTER]
 	dec a
 	ld bc,3
 .loop\@
@@ -64282,9 +64282,9 @@
 	ld [W_FBMODE],a
 	call DrawFrameBlock
 	call $4ED7 ; run animation-specific function (if there is one)
-	ld a,[W_SUBANIMSIZE]
+	ld a,[W_SUBANIMCOUNTER]
 	dec a
-	ld [W_SUBANIMSIZE],a
+	ld [W_SUBANIMCOUNTER],a
 	ret z
 	ld a,[W_SUBANIMSUBENTRYADDR + 1]
 	ld h,a
@@ -64343,85 +64343,350 @@
 ; Format: Animation ID (1 byte), Address (2 bytes)
 AnimationIdSpecialEffects: ; 4EF5
 	db MEGA_PUNCH
-	dw $51BE
+	dw AnimationFlashScreen
 
 	db GUILLOTINE
-	dw $51BE
+	dw AnimationFlashScreen
 
 	db MEGA_KICK
-	dw $51BE
+	dw AnimationFlashScreen
 
 	db HEADBUTT
-	dw $51BE
+	dw AnimationFlashScreen
 
 	db TAIL_WHIP
-	dw $50D0
+	dw Func50D0
 
 	db GROWL
-	dw $50BC
+	dw DoGrowlSpecialEffects
 
 	db DISABLE
-	dw $51BE
+	dw AnimationFlashScreen
 
 	db BLIZZARD
-	dw $5016
+	dw DoBlizzardSpecialEffects
 
 	db BUBBLEBEAM
-	dw $51BE
+	dw AnimationFlashScreen
 
 	db HYPER_BEAM
-	dw $5000
+	dw FlashScreenEveryFourFrameBlocks
 
 	db THUNDERBOLT
-	dw $4FF7
+	dw FlashScreenEveryEightFrameBlocks
 
 	db REFLECT
-	dw $51BE
+	dw AnimationFlashScreen
 
 	db SELFDESTRUCT
-	dw $5009
+	dw DoExplodeSpecialEffects
 
 	db SPORE
-	dw $51BE
+	dw AnimationFlashScreen
 
 	db EXPLOSION
-	dw $5009
+	dw DoExplodeSpecialEffects
 
 	db ROCK_SLIDE
-	dw $4FD9
+	dw DoRockSlideSpecialEffects
 
 	db $AA
-	dw $5041
+	dw Func5041
 
 	db $AB
-	dw $504C
+	dw Func504C
 
 	db $AC
-	dw $507C
+	dw Func507C
 
 	db TOSS_ANIM
-	dw $4F3E
+	dw DoBallTossSpecialEffects
 
-	db $C2
-	dw $4F96
+	db SHAKE_ANIM
+	dw DoBallShakeSpecialEffects
 
 	db POOF_ANIM
-	dw $4FCE
+	dw DoPoofSpecialEffects
 
 	db GREATTOSS_ANIM
-	dw $4F3E
+	dw DoBallTossSpecialEffects
 
 	db ULTRATOSS_ANIM
-	dw $4F3E
+	dw DoBallTossSpecialEffects
 
 	db $FF ; terminator
 
-INCBIN "baserom.gbc",$78F3E,$790DA - $78F3E
+DoBallTossSpecialEffects: ; 4F3E
+	ld a,[$CF91]
+	cp a,3 ; is it a Master Ball or Ultra Ball?
+	jr nc,.skipFlashingEffect\@
+.flashingEffect\@ ; do a flashing effect if it's Master Ball or Ultra Ball
+	ld a,[rOBP0]
+	xor a,%00111100 ; complement colors 1 and 2
+	ld [rOBP0],a
+.skipFlashingEffect\@
+	ld a,[W_SUBANIMCOUNTER]
+	cp a,11 ; is it the beginning of the subanimation?
+	jr nz,.skipPlayingSound\@
+; if it is the beginning of the subanimation, play a sound
+	ld a,$91
+	call $23b1 ; play sound
+.skipPlayingSound\@
+	ld a,[W_ISINBATTLE]
+	cp a,02 ; is it a trainer battle?
+	jr z,.isTrainerBattle\@
+	ld a,[$d11e]
+	cp a,$10 ; is the enemy pokemon the Ghost Marowak?
+	ret nz
+; if the enemy pokemon is the Ghost Marowak, make it dodge during the last 3 frames
+	ld a,[W_SUBANIMCOUNTER]
+	cp a,3
+	jr z,.moveGhostMarowakLeft\@
+	cp a,2
+	jr z,.moveGhostMarowakLeft\@
+	cp a,1
+	ret nz
+.moveGhostMarowakLeft\@
+	FuncCoord 17,0
+	ld hl,Coord
+	ld de,20
+	ld bc,$0707 ; 7 rows and 7 columns
+.loop\@
+	push hl
+	push bc
+	call $5862 ; move row of tiles left
+	pop bc
+	pop hl
+	add hl,de
+	dec b
+	jr nz,.loop\@
+	ld a,%00001000
+	ld [$ff10],a ; Channel 1 sweep register
+	ret
+.isTrainerBattle\@ ; if it's a trainer battle, shorten the animation by one frame
+	ld a,[W_SUBANIMCOUNTER]
+	cp a,3
+	ret nz
+	dec a
+	ld [W_SUBANIMCOUNTER],a
+	ret
 
+DoBallShakeSpecialEffects: ; 4F96
+	ld a,[W_SUBANIMCOUNTER]
+	cp a,4 ; is it the beginning of a shake?
+	jr nz,.skipPlayingSound\@
+; if it is the beginning of a shake, play a sound and wait 2/3 of a second
+	ld a,$8c
+	call $23b1 ; play sound
+	ld c,40
+	call DelayFrames
+.skipPlayingSound\@
+	ld a,[W_SUBANIMCOUNTER]
+	dec a
+	ret nz
+; if it's the end of the ball shaking subanimation, check if more shakes are left and restart the subanimation
+	ld a,[$cd3d] ; number of shakes
+	dec a ; decrement number of shakes
+	ld [$cd3d],a
+	ret z
+; if there are shakes left, restart the subanimation
+	ld a,[W_SUBANIMSUBENTRYADDR]
+	ld l,a
+	ld a,[W_SUBANIMSUBENTRYADDR + 1]
+	ld h,a
+	ld de,-(4 * 3) ; 4 subentries and 3 bytes per subentry
+	add hl,de
+	ld a,l
+	ld [W_SUBANIMSUBENTRYADDR],a
+	ld a,h
+	ld [W_SUBANIMSUBENTRYADDR + 1],a
+	ld a,5 ; number of subentries in the ball shaking subanimation plus one
+	ld [W_SUBANIMCOUNTER],a
+	ret
+
+; plays a sound after the second frame of the poof animation
+DoPoofSpecialEffects: ; 4FCE
+	ld a,[W_SUBANIMCOUNTER]
+	cp a,5
+	ret nz
+	ld a,$93
+	jp $23b1
+
+DoRockSlideSpecialEffects: ; 4FD9
+	ld a,[W_SUBANIMCOUNTER]
+	cp a,12
+	ret nc
+	cp a,8
+	jr nc,.shakeScreen\@
+	cp a,1
+	jp z,AnimationFlashScreen ; if it's the end of the subanimation, flash the screen
+	ret
+; if the subaninmation counter is between 8 and 11, shake the screen horizontally and vertically
+.shakeScreen\@
+	ld b,1
+	ld a,$24
+	call Predef ; shake horizontally
+	ld b,1
+	ld a,$21
+	jp Predef ; shake vertically
+
+FlashScreenEveryEightFrameBlocks: ; 4FF7
+	ld a,[W_SUBANIMCOUNTER]
+	and a,7 ; is the subanimation counter exactly 8?
+	call z,AnimationFlashScreen ; if so, flash the screen
+	ret
+
+; flashes the screen if the subanimation counter is divisible by 4
+FlashScreenEveryFourFrameBlocks: ; 5000
+	ld a,[W_SUBANIMCOUNTER]
+	and a,3
+	call z,AnimationFlashScreen
+	ret
+
+; used for Explosion and Selfdestruct
+DoExplodeSpecialEffects: ; 5009
+	ld a,[W_SUBANIMCOUNTER]
+	cp a,1 ; is it the end of the subanimation?
+	jr nz,FlashScreenEveryFourFrameBlocks
+; if it's the end of the subanimation, make the attacking pokemon disappear
+	ld hl,$C405
+	jp $5801 ; make pokemon disappear
+
+; flashes the screen when subanimation counter is 1 modulo 4
+DoBlizzardSpecialEffects: ; 5016
+	ld a,[W_SUBANIMCOUNTER]
+	cp a,13
+	jp z,AnimationFlashScreen
+	cp a,9
+	jp z,AnimationFlashScreen
+	cp a,5
+	jp z,AnimationFlashScreen
+	cp a,1
+	jp z,AnimationFlashScreen
+	ret
+
+; flashes the screen at 3 points in the subanimation
+; XXX is this unused?
+Func502E: ; 502E
+	ld a,[W_SUBANIMCOUNTER]
+	cp a,14
+	jp z,AnimationFlashScreen
+	cp a,9
+	jp z,AnimationFlashScreen
+	cp a,2
+	jp z,AnimationFlashScreen
+	ret
+
+; function to make the pokemon disappear at the beginning of the animation
+; XXX probably a trade-related animation
+Func5041:
+	ld a,[W_SUBANIMCOUNTER]
+	cp a,6
+	ret nz
+	ld a,$2F
+	jp $580C ; make pokemon disappear
+
+; function to make a shaking pokeball jump up at the end of the animation
+; XXX probably a trade-related animation
+Func504C:
+	ld a,[W_SUBANIMCOUNTER]
+	cp a,1
+	ret nz
+; if it's the end of the animation, make the ball jump up
+	ld de,BallMoveDistances1
+.loop\@
+	ld hl,$c300 ; OAM buffer
+	ld bc,4
+.innerLoop\@
+	ld a,[de]
+	cp a,$ff
+	jr z,.done\@
+	add [hl] ; add to Y value of OAM entry
+	ld [hl],a
+	add hl,bc
+	ld a,l
+	cp a,4 * 4 ; there are 4 entries, each 4 bytes
+	jr nz,.innerLoop\@
+	inc de
+	push bc
+	call Delay3
+	pop bc
+	jr .loop\@
+.done\@
+	call AnimationCleanOAM
+	ld a,$98
+	jp $23B1 ; play sound
+
+BallMoveDistances1: ; 5078
+db -12,-12,-8
+db $ff ; terminator
+
+; function to make the pokeball jump up
+; XXX probably a trade-related animation
+Func507C ; 507C
+	ld de,BallMoveDistances2
+.loop\@
+	ld hl,$c300 ; OAM buffer
+	ld bc,4
+.innerLoop\@
+	ld a,[de]
+	cp a,$ff
+	jp z,ClearScreen
+	add [hl]
+	ld [hl],a
+	add hl,bc
+	ld a,l
+	cp a,4 * 4 ; there are 4 entries, each 4 bytes
+	jr nz,.innerLoop\@
+	inc de
+	push de
+	ld a,[de]
+	cp a,12
+	jr z,.playSound\@
+	cp a,$ff
+	jr nz,.skipPlayingSound\@
+.playSound\@ ; play sound if next move distance is 12 or this is the last one
+	ld a,$ae
+	call $23b1
+.skipPlayingSound\@
+	push bc
+	ld c,5
+	call DelayFrames
+	pop bc
+	ld a,[$ffae] ; background scroll X
+	sub a,8 ; scroll to the left
+	ld [$ffae],a
+	pop de
+	jr .loop\@
+
+BallMoveDistances2: ; 50B3
+db 11,12,-12,-7,7,12,-8,8
+db $ff ; terminator
+
+; this function copies the current musical note graphic
+; so that there are two musical notes flying towards the defending pokemon
+DoGrowlSpecialEffects: ; 50BC
+	ld hl,$c300 ; OAM buffer
+	ld de,$c310
+	ld bc,$10
+	call CopyData ; copy the musical note graphic
+	ld a,[W_SUBANIMCOUNTER]
+	dec a
+	call z,AnimationCleanOAM ; clean up at the end of the subanimation
+	ret
+
+; this is associated with Tail Whip, but Tail Whip doesn't use any subanimations
+; XXX why is this here?
+Func50D0: ; 50D0
+	ld a,1
+	ld [W_SUBANIMCOUNTER],a
+	ld c,20
+	jp DelayFrames
+
 ; Format: Special Effect ID (1 byte), Address (2 bytes)
 SpecialEffectPointers: ; 50DA
 	db $FE
-	dw $51BE
+	dw AnimationFlashScreen
 	db $FD
 	dw $51D6
 	db $FC
@@ -64433,7 +64698,7 @@
 	db $F9
 	dw $51DB
 	db $F8
-	dw $5165
+	dw AnimationFlashScreenLong
 	db $F7
 	dw $527A
 	db $F6
@@ -64479,7 +64744,7 @@
 	db $E2
 	dw $5424
 	db $E1
-	dw $5150
+	dw AnimationDelay10
 	db $E0
 	dw $5398
 	db $DF
@@ -64500,7 +64765,114 @@
 	dw $5666
 	db $FF
 
-INCBIN "baserom.gbc",$79150,$7986F - $79150
+AnimationDelay10: ; 5150
+	ld c,10
+	jp DelayFrames
+
+; calls a function with the turn flipped from player to enemy or vice versa
+; input - hl - address of function to call
+CallWithTurnFlipped: ; 5155
+	ld a,[H_WHOSETURN]
+	push af
+	xor a,1
+	ld [H_WHOSETURN],a
+	ld de,.returnAddress\@
+	push de
+	jp [hl]
+.returnAddress\@
+	pop af
+	ld [H_WHOSETURN],a
+	ret 
+
+; flashes the screen for an extended period (48 frames)
+AnimationFlashScreenLong: ; 5165
+	ld a,3 ; cycle through the palettes 3 times
+	ld [$D08A],a
+	ld a,[$cf1b] ; running on SGB?
+	and a
+	ld hl,FlashScreenLongMonochrome
+	jr z,.loop\@
+	ld hl,FlashScreenLongSGB
+.loop\@
+	push hl
+.innerLoop\@
+	ld a,[hli]
+	cp a,$01 ; is it the end of the palettes?
+	jr z,.endOfPalettes\@
+	ld [rBGP],a
+	call FlashScreenLongDelay
+	jr .innerLoop\@
+.endOfPalettes\@
+	ld a,[$D08A]
+	dec a
+	ld [$D08A],a
+	pop hl
+	jr nz,.loop\@
+	ret 
+
+; BG palettes
+FlashScreenLongMonochrome: ; 518E
+db %11111001 ; 3, 3, 2, 1
+db %11111110 ; 3, 3, 3, 2
+db %11111111 ; 3, 3, 3, 3
+db %11111110 ; 3, 3, 3, 2
+db %11111001 ; 3, 3, 2, 1
+db %11100100 ; 3, 2, 1, 0
+db %10010000 ; 2, 1, 0, 0
+db %01000000 ; 1, 0, 0, 0
+db %00000000 ; 0, 0, 0, 0
+db %01000000 ; 1, 0, 0, 0
+db %10010000 ; 2, 1, 0, 0
+db %11100100 ; 3, 2, 1, 0
+db $01 ; terminator
+
+; BG palettes
+FlashScreenLongSGB: ; 519B
+db %11111000 ; 3, 3, 2, 0
+db %11111100 ; 3, 3, 3, 0
+db %11111111 ; 3, 3, 3, 3
+db %11111100 ; 3, 3, 3, 0
+db %11111000 ; 3, 3, 2, 0
+db %11100100 ; 3, 2, 1, 0
+db %10010000 ; 2, 1, 0, 0
+db %01000000 ; 1, 0, 0, 0
+db %00000000 ; 0, 0, 0, 0
+db %01000000 ; 1, 0, 0, 0
+db %10010000 ; 2, 1, 0, 0
+db %11100100 ; 3, 2, 1, 0
+db $01 ; terminator
+
+; causes a delay of 2 frames for the first cycle
+; causes a delay of 1 frame for the second and third cycles
+FlashScreenLongDelay: ; 51A8
+	ld a,[$D08A]
+	cp a,4 ; never true since [$D08A] starts at 3
+	ld c,4
+	jr z,.delayFrames\@
+	cp a,3
+	ld c,2
+	jr z,.delayFrames\@
+	cp a,2 ; nothing is done with this
+	ld c,1
+.delayFrames\@
+	jp DelayFrames
+
+AnimationFlashScreen: ; 51BE
+	ld a,[rBGP]
+	push af ; save initial palette
+	ld a,%00011011 ; 0, 1, 2, 3 (inverted colors)
+	ld [rBGP],a
+	ld c,2
+	call DelayFrames
+	xor a ; white out background
+	ld [rBGP],a
+	ld c,2
+	call DelayFrames
+	pop af
+	ld [rBGP],a ; restore initial palette
+	ret
+
+INCBIN "baserom.gbc",$791D6,$7986F - $791D6
 
 Func586F: ; 0x7986F 586F
 	ld hl,MoveSoundTable