aboutsummaryrefslogtreecommitdiffstats
path: root/engine/movie
diff options
context:
space:
mode:
authordannye <33dannye@gmail.com>2020-11-04 00:06:44 -0600
committerdannye <33dannye@gmail.com>2020-11-04 00:06:44 -0600
commit5647ca687b92954dcf37a6ea6bfbc9a341c32de4 (patch)
treedde1937a1bfdb3a835f4155e1c2eb8f1aaf86f63 /engine/movie
parentMerge pull request #55 from Deokishisu/patch-1 (diff)
downloadpokeyellow-5647ca687b92954dcf37a6ea6bfbc9a341c32de4.tar.gz
pokeyellow-5647ca687b92954dcf37a6ea6bfbc9a341c32de4.tar.xz
pokeyellow-5647ca687b92954dcf37a6ea6bfbc9a341c32de4.zip
Sync with pokered
Diffstat (limited to 'engine/movie')
-rwxr-xr-xengine/movie/credits.asm322
-rwxr-xr-xengine/movie/evolution.asm156
-rwxr-xr-xengine/movie/hall_of_fame.asm303
-rwxr-xr-xengine/movie/intro.asm157
-rwxr-xr-xengine/movie/oak_speech/clear_save.asm27
-rw-r--r--engine/movie/oak_speech/init_player_data.asm60
-rwxr-xr-xengine/movie/oak_speech/oak_speech.asm244
-rwxr-xr-xengine/movie/oak_speech/oak_speech2.asm219
-rwxr-xr-xengine/movie/splash.asm259
-rwxr-xr-xengine/movie/title.asm370
-rwxr-xr-xengine/movie/title2.asm122
-rwxr-xr-xengine/movie/trade.asm859
-rwxr-xr-xengine/movie/trade2.asm49
13 files changed, 3147 insertions, 0 deletions
diff --git a/engine/movie/credits.asm b/engine/movie/credits.asm
new file mode 100755
index 00000000..938579f3
--- /dev/null
+++ b/engine/movie/credits.asm
@@ -0,0 +1,322 @@
+HallOfFamePC:
+ callfar AnimateHallOfFame
+ call ClearScreen
+ ld c, 100
+ call DelayFrames
+
+ call DisableLCD
+ ld a, $a7
+ ldh [rWX], a
+ xor a
+ ldh [rSCX], a
+ ldh [rSCY], a
+ ldh [hSCX], a
+ ldh [hSCY], a
+ ldh [hWY], a
+ ldh [rWY], a
+ call CreditsLoadFont
+ hlcoord 0, 0
+ call FillFourRowsWithBlack
+ hlcoord 0, 14
+ call FillFourRowsWithBlack
+ ld a, %11000000
+ ldh [rBGP], a
+ call UpdateGBCPal_BGP
+ call EnableLCD
+ call StopAllMusic
+ ld hl, vBGMap1
+ call CreditsCopyTileMapToVRAM
+ ld hl, vBGMap0
+ call CreditsCopyTileMapToVRAM
+ ld c, BANK(Music_Credits)
+ ld a, MUSIC_CREDITS
+ call PlayMusic
+ ld c, 128
+ call DelayFrames
+ xor a
+ ld [wHoFMonSpecies], a
+ ld [wNumCreditsMonsDisplayed], a
+ jp Credits
+
+FadeInCreditsText:
+ ld a, 1
+ ldh [hAutoBGTransferEnabled], a
+ ld hl, HoFGBPalettes
+ ld b, 4
+.loop
+ ld a, [hli]
+ ldh [rBGP], a
+ call UpdateGBCPal_BGP
+ ld c, 5
+ call DelayFrames
+ dec b
+ jr nz, .loop
+ ret
+
+HoFGBPalettes:
+ db %11000000
+ db %11010000
+ db %11100000
+ db %11110000
+
+DisplayCreditsMon:
+ ld hl, vBGMap1
+ call CreditsCopyTileMapToVRAM
+ xor a
+ ldh [hAutoBGTransferEnabled], a
+ ld hl, rLCDC
+ set 3, [hl]
+ call SaveScreenTilesToBuffer2
+ call FillMiddleOfScreenWithWhite
+ call GetNextCreditsMon
+ ld hl, vBGMap0 + 12
+ call CreditsCopyTileMapToVRAM
+ xor a
+ ldh [hAutoBGTransferEnabled], a
+ call LoadScreenTilesFromBuffer2DisableBGTransfer
+ ld hl, vBGMap0
+ call CreditsCopyTileMapToVRAM
+ ld a, %11111100 ; make the mon a black silhouette
+ ldh [rBGP], a
+ call UpdateGBCPal_BGP
+ ld hl, rLCDC
+ res 3, [hl]
+ ld a, 1
+ ldh [hAutoBGTransferEnabled], a
+ ld b, 0
+ ld c, 10
+ call ScrollCreditsMonLeft
+ call FillLeftHalfOfScreenWithWhite
+ ld c, 10
+ call ScrollCreditsMonLeft
+ call FillRightHalfOfScreenWithWhite
+ ld c, 8
+ call ScrollCreditsMonLeft
+ ld a, %11000000
+ ldh [rBGP], a
+ call UpdateGBCPal_BGP
+ xor a
+ ldh [hSCX], a
+ ret
+
+ScrollCreditsMonLeft:
+ ld a, b
+ ldh [hSCX], a
+ add 8
+ ld b, a
+ call DelayFrame
+ dec c
+ jr nz, ScrollCreditsMonLeft
+ ret
+
+GetNextCreditsMon:
+ ld hl, wNumCreditsMonsDisplayed
+ ld c, [hl]
+ inc [hl]
+ ld b, 0
+ ld hl, CreditsMons
+ add hl, bc
+ ld a, [hl]
+ ld [wcf91], a
+ ld [wd0b5], a
+ hlcoord 8, 6
+ call GetMonHeader
+ call LoadFrontSpriteByMonIndex
+ ret
+
+INCLUDE "data/credits/credits_mons.asm"
+
+CreditsCopyTileMapToVRAM:
+ ld a, l
+ ldh [hAutoBGTransferDest], a
+ ld a, h
+ ldh [hAutoBGTransferDest + 1], a
+ ld a, 1
+ ldh [hAutoBGTransferEnabled], a
+ jp Delay3
+
+CreditsLoadFont:
+ call LoadFontTilePatterns
+ ld hl, vChars1
+ ld bc, ($80 tiles) / 2
+ call ZeroMemory
+
+ call LoadTextBoxTilePatterns
+ ld hl, vChars2 tile $60
+ ld bc, ($20 tiles) / 2
+ call ZeroMemory
+
+ ld hl, vChars2 tile $7e
+ ld bc, 1 tiles
+ ld a, $ff ; solid black
+ call FillMemory
+ ret
+
+ZeroMemory:
+; zero bc bytes at hl
+ ld [hl], 0
+ inc hl
+ inc hl
+ dec bc
+ ld a, b
+ or c
+ jr nz, ZeroMemory
+ ret
+
+FillFourRowsWithBlack:
+ ld bc, SCREEN_WIDTH * 4
+ ld a, $7e
+ jp FillMemory
+
+FillMiddleOfScreenWithWhite:
+ hlcoord 0, 4
+ ld bc, SCREEN_WIDTH * 10
+ ld a, " "
+ jp FillMemory
+
+FillLeftHalfOfScreenWithWhite:
+ hlcoord 0, 4
+ push bc
+ call FillHalfOfScreenWithWhite
+ pop bc
+ ret
+
+FillRightHalfOfScreenWithWhite:
+ hlcoord 10, 4
+ push bc
+ call FillHalfOfScreenWithWhite
+ pop bc
+ ret
+
+FillHalfOfScreenWithWhite:
+ ld b, 10
+ ld c, 10
+ ld a, " "
+.loop
+ push bc
+ push hl
+.innerLoop
+ ld [hli], a
+ dec c
+ jr nz, .innerLoop
+ pop hl
+ ld bc, SCREEN_WIDTH
+ add hl, bc
+ pop bc
+ dec b
+ jr nz, .loop
+ ret
+
+Credits: ; Roll credits
+ ld de, CreditsOrder
+ push de
+.nextCreditsScreen
+ pop de
+ hlcoord 9, 6
+ push hl
+ call FillMiddleOfScreenWithWhite
+ pop hl
+.nextCreditsCommand
+ ld a, [de]
+ inc de
+ push de
+ cp CRED_TEXT_FADE_MON
+ jr z, .fadeInTextAndShowMon
+ cp CRED_TEXT_MON
+ jr z, .showTextAndShowMon
+ cp CRED_TEXT_FADE
+ jr z, .fadeInText
+ cp CRED_TEXT
+ jr z, .showText
+ cp CRED_COPYRIGHT
+ jr z, .showCopyrightText
+ cp CRED_THE_END
+ jr z, .showTheEnd
+ call PlaceCreditsText
+ pop de
+ jr .nextCreditsCommand
+
+.showCopyrightText
+ farcall LoadCopyrightTiles
+ pop de
+ jr .nextCreditsCommand
+
+
+.fadeInTextAndShowMon
+ call FadeInCreditsText
+ ld c, 102
+ jr .next1
+
+.showTextAndShowMon
+ ld c, 122
+.next1
+ call DelayFrames
+ call DisplayCreditsMon
+ jr .nextCreditsScreen
+
+.fadeInText
+ call FadeInCreditsText
+ ld c, 132
+ jr .next2
+
+.showText
+ ld c, 152
+.next2
+ call DelayFrames
+ jr .nextCreditsScreen
+.showTheEnd
+ call ShowTheEndGFX
+ pop de
+ ret
+
+ShowTheEndGFX:
+ ld c, 24
+ call DelayFrames
+ call FillMiddleOfScreenWithWhite
+ ld de, TheEndGfx
+ ld hl, vChars2 tile $60
+ lb bc, BANK(TheEndGfx), (TheEndGfxEnd - TheEndGfx) / $10
+ call CopyVideoData
+ hlcoord 4, 8
+ ld de, TheEndTextString
+ call PlaceString
+ hlcoord 4, 9
+ inc de
+ call PlaceString
+ jp FadeInCreditsText
+
+TheEndTextString:
+; "T H E E N D"
+ db $60, " ", $62, " ", $64, " ", $64, " ", $66, " ", $68, "@"
+ db $61, " ", $63, " ", $65, " ", $65, " ", $67, " ", $69, "@"
+
+PlaceCreditsText:
+ push hl
+ push hl
+ ld hl, CreditsTextPointers
+ ld c, a
+ ld b, 0
+ add hl, bc
+ add hl, bc
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ pop hl
+ ld a, [de]
+ inc de
+ ld c, a
+ ld b, -1
+ add hl, bc
+ call PlaceString
+ pop hl
+ ld bc, SCREEN_WIDTH * 2
+ add hl, bc
+ ret
+
+INCLUDE "data/credits/credits_order.asm"
+
+INCLUDE "data/credits/credits_text.asm"
+
+TheEndGfx:
+ INCBIN "gfx/credits/the_end.2bpp"
+TheEndGfxEnd:
diff --git a/engine/movie/evolution.asm b/engine/movie/evolution.asm
new file mode 100755
index 00000000..624a7f5f
--- /dev/null
+++ b/engine/movie/evolution.asm
@@ -0,0 +1,156 @@
+EvolveMon:
+ push hl
+ push de
+ push bc
+ ld a, [wcf91]
+ push af
+ ld a, [wd0b5]
+ push af
+ xor a
+ ld [wLowHealthAlarm], a
+ ld [wChannelSoundIDs + Ch5], a
+ call StopAllMusic
+ ld a, $1
+ ldh [hAutoBGTransferEnabled], a
+ ld a, SFX_TINK
+ call PlaySound
+ call Delay3
+ xor a
+ ldh [hAutoBGTransferEnabled], a
+ ldh [hTilesetType], a
+ ld a, [wEvoOldSpecies]
+ ld [wWholeScreenPaletteMonSpecies], a
+ ld c, 0
+ call EvolutionSetWholeScreenPalette
+ ld a, [wEvoNewSpecies]
+ ld [wcf91], a
+ ld [wd0b5], a
+ call Evolution_LoadPic
+ ld de, vFrontPic
+ ld hl, vBackPic
+ ld bc, 7 * 7
+ call CopyVideoData
+ ld a, [wEvoOldSpecies]
+ ld [wcf91], a
+ ld [wd0b5], a
+ call Evolution_LoadPic
+ ld a, $1
+ ldh [hAutoBGTransferEnabled], a
+ ld a, [wEvoOldSpecies]
+ call PlayCry
+ call WaitForSoundToFinish
+ ld c, BANK(Music_SafariZone)
+ ld a, MUSIC_SAFARI_ZONE
+ call PlayMusic
+ ld c, 80
+ call DelayFrames
+ ld c, 1 ; set PAL_BLACK instead of mon palette
+ call EvolutionSetWholeScreenPalette
+ lb bc, $1, $10
+.animLoop
+ push bc
+ call Evolution_CheckForCancel
+ jr c, .evolutionCancelled
+ call Evolution_BackAndForthAnim
+ pop bc
+ inc b
+ dec c
+ dec c
+ jr nz, .animLoop
+ xor a
+ ld [wEvoCancelled], a
+ ld a, $31
+ ld [wEvoMonTileOffset], a
+ call Evolution_ChangeMonPic ; show the new species pic
+ ld a, [wEvoNewSpecies]
+.done
+ ld [wWholeScreenPaletteMonSpecies], a
+ call StopAllMusic
+ ld a, [wWholeScreenPaletteMonSpecies]
+ call PlayCry
+ ld c, 0
+ call EvolutionSetWholeScreenPalette
+ pop af
+ ld [wd0b5], a
+ pop af
+ ld [wcf91], a
+ pop bc
+ pop de
+ pop hl
+ ld a, [wEvoCancelled]
+ and a
+ ret z
+ scf
+ ret
+.evolutionCancelled
+ pop bc
+ ld a, 1
+ ld [wEvoCancelled], a
+ ld a, [wEvoOldSpecies]
+ jr .done
+
+EvolutionSetWholeScreenPalette:
+ ld b, SET_PAL_POKEMON_WHOLE_SCREEN
+ jp RunPaletteCommand
+
+Evolution_LoadPic:
+ call GetMonHeader
+ hlcoord 7, 2
+ jp LoadFlippedFrontSpriteByMonIndex
+
+Evolution_BackAndForthAnim:
+; show the mon change back and forth between the new and old species b times
+ ld a, $31
+ ld [wEvoMonTileOffset], a
+ call Evolution_ChangeMonPic
+ ld a, -$31
+ ld [wEvoMonTileOffset], a
+ call Evolution_ChangeMonPic
+ dec b
+ jr nz, Evolution_BackAndForthAnim
+ ret
+
+Evolution_ChangeMonPic:
+ push bc
+ xor a
+ ldh [hAutoBGTransferEnabled], a
+ hlcoord 7, 2
+ lb bc, 7, 7
+ ld de, SCREEN_WIDTH - 7
+.loop
+ push bc
+.innerLoop
+ ld a, [wEvoMonTileOffset]
+ add [hl]
+ ld [hli], a
+ dec c
+ jr nz, .innerLoop
+ pop bc
+ add hl, de
+ dec b
+ jr nz, .loop
+ ld a, 1
+ ldh [hAutoBGTransferEnabled], a
+ call Delay3
+ pop bc
+ ret
+
+Evolution_CheckForCancel:
+ call DelayFrame
+ push bc
+ call JoypadLowSensitivity
+ ldh a, [hJoy5]
+ pop bc
+ and B_BUTTON
+ jr nz, .pressedB
+.notAllowedToCancel
+ dec c
+ jr nz, Evolution_CheckForCancel
+ and a
+ ret
+.pressedB
+ ld a, [wForceEvolution]
+ and a
+ jr nz, .notAllowedToCancel
+ scf
+ ret
diff --git a/engine/movie/hall_of_fame.asm b/engine/movie/hall_of_fame.asm
new file mode 100755
index 00000000..616a72e3
--- /dev/null
+++ b/engine/movie/hall_of_fame.asm
@@ -0,0 +1,303 @@
+AnimateHallOfFame:
+ call HoFFadeOutScreenAndMusic
+ call ClearScreen
+ ld c, 100
+ call DelayFrames
+ call LoadFontTilePatterns
+ call LoadTextBoxTilePatterns
+ call DisableLCD
+ ld hl, vBGMap0
+ ld bc, $800
+ ld a, " "
+ call FillMemory
+ call EnableLCD
+ ld hl, rLCDC
+ set 3, [hl]
+ xor a
+ ld hl, wHallOfFame
+ ld bc, HOF_TEAM
+ call FillMemory
+ xor a
+ ld [wUpdateSpritesEnabled], a
+ ldh [hTilesetType], a
+ ld [wSpriteFlipped], a
+ ld [wLetterPrintingDelayFlags], a ; no delay
+ ld [wHoFMonOrPlayer], a ; mon
+ inc a
+ ldh [hAutoBGTransferEnabled], a
+ ld hl, wNumHoFTeams
+ ld a, [hl]
+ inc a
+ jr z, .skipInc ; don't wrap around to 0
+ inc [hl]
+.skipInc
+ ld a, $90
+ ldh [hWY], a
+ ld c, BANK(Music_HallOfFame)
+ ld a, MUSIC_HALL_OF_FAME
+ call PlayMusic
+ ld hl, wPartySpecies
+ ld c, $ff
+.partyMonLoop
+ ld a, [hli]
+ cp $ff
+ jr z, .doneShowingParty
+ inc c
+ push hl
+ push bc
+ ld [wHoFMonSpecies], a
+ ld a, c
+ ld [wHoFPartyMonIndex], a
+ ld hl, wPartyMon1Level
+ ld bc, wPartyMon2 - wPartyMon1
+ call AddNTimes
+ ld a, [hl]
+ ld [wHoFMonLevel], a
+ call HoFShowMonOrPlayer
+ call HoFDisplayAndRecordMonInfo
+ ld c, 80
+ call DelayFrames
+ hlcoord 2, 13
+ lb bc, 3, 14
+ call TextBoxBorder
+ hlcoord 4, 15
+ ld de, HallOfFameText
+ call PlaceString
+ ld c, 180
+ call DelayFrames
+ call GBFadeOutToWhite
+ pop bc
+ pop hl
+ jr .partyMonLoop
+.doneShowingParty
+ ld a, c
+ inc a
+ ld hl, wHallOfFame
+ ld bc, HOF_MON
+ call AddNTimes
+ ld [hl], $ff
+ callfar SaveHallOfFameTeams ; useless since in same bank
+ xor a
+ ld [wHoFMonSpecies], a
+ inc a
+ ld [wHoFMonOrPlayer], a ; player
+ call HoFShowMonOrPlayer
+ call HoFDisplayPlayerStats
+ call HoFFadeOutScreenAndMusic
+ xor a
+ ldh [hWY], a
+ ld hl, rLCDC
+ res 3, [hl]
+ ret
+
+HallOfFameText:
+ db "HALL OF FAME@"
+
+HoFShowMonOrPlayer:
+ call ClearScreen
+ ld a, $d0
+ ldh [hSCY], a
+ ld a, $c0
+ ldh [hSCX], a
+ ld a, [wHoFMonSpecies]
+ ld [wcf91], a
+ ld [wd0b5], a
+ ld [wBattleMonSpecies2], a
+ ld [wWholeScreenPaletteMonSpecies], a
+ ld a, [wHoFMonOrPlayer]
+ and a
+ jr z, .showMon
+; show player
+ call HoFLoadPlayerPics
+ jr .next1
+.showMon
+ hlcoord 12, 5
+ call GetMonHeader
+ call LoadFrontSpriteByMonIndex
+ predef LoadMonBackPic
+.next1
+ ld b, SET_PAL_POKEMON_WHOLE_SCREEN
+ ld c, 0
+ call RunPaletteCommand
+ ld a, %11100100
+ ldh [rBGP], a
+ call UpdateGBCPal_BGP
+ ld c, $31 ; back pic
+ call HoFLoadMonPlayerPicTileIDs
+ ld d, $a0
+ ld e, 4
+ ld a, [wOnSGB]
+ and a
+ jr z, .next2
+ sla e ; scroll more slowly on SGB
+.next2
+ call .ScrollPic ; scroll back pic left
+ xor a
+ ldh [hSCY], a
+ ld c, a ; front pic
+ call HoFLoadMonPlayerPicTileIDs
+ ld d, 0
+ ld e, -4
+; scroll front pic right
+
+.ScrollPic
+ call DelayFrame
+ ldh a, [hSCX]
+ add e
+ ldh [hSCX], a
+ cp d
+ jr nz, .ScrollPic
+ ret
+
+HoFDisplayAndRecordMonInfo:
+ ld a, [wHoFPartyMonIndex]
+ ld hl, wPartyMonNicks
+ call GetPartyMonName
+ call HoFDisplayMonInfo
+ ld a, [wHoFPartyMonIndex]
+ ld [wWhichPokemon], a
+ callfar IsThisPartymonStarterPikachu_Party
+ jr nc, .asm_70336
+ ld e, $22
+ callfar PlayPikachuSoundClip
+ jr .asm_7033c
+.asm_70336
+ ld a, [wHoFMonSpecies]
+ call PlayCry
+.asm_7033c
+ jp HoFRecordMonInfo
+
+Func_7033f:
+ call HoFDisplayMonInfo
+ ld a, [wHoFMonSpecies]
+ jp PlayCry
+
+HoFDisplayMonInfo:
+ hlcoord 0, 2
+ lb bc, 9, 10
+ call TextBoxBorder
+ hlcoord 2, 6
+ ld de, HoFMonInfoText
+ call PlaceString
+ hlcoord 1, 4
+ ld de, wcd6d
+ call PlaceString
+ ld a, [wHoFMonLevel]
+ hlcoord 8, 7
+ call PrintLevelCommon
+ ld a, [wHoFMonSpecies]
+ ld [wd0b5], a
+ hlcoord 3, 9
+ predef PrintMonType
+ ret
+
+HoFMonInfoText:
+ db "LEVEL/"
+ next "TYPE1/"
+ next "TYPE2/@"
+
+HoFLoadPlayerPics:
+ ld de, RedPicFront
+ ld a, BANK(RedPicFront)
+ call UncompressSpriteFromDE
+ ld a, $0
+ call SwitchSRAMBankAndLatchClockData
+ ld hl, sSpriteBuffer1
+ ld de, sSpriteBuffer0
+ ld bc, $310
+ call CopyData
+ call PrepareRTCDataAndDisableSRAM
+ ld de, vFrontPic
+ call InterlaceMergeSpriteBuffers
+ ld de, RedPicBack
+ ld a, BANK(RedPicBack)
+ call UncompressSpriteFromDE
+ predef ScaleSpriteByTwo
+ ld de, vBackPic
+ call InterlaceMergeSpriteBuffers
+ ld c, $1
+
+HoFLoadMonPlayerPicTileIDs:
+; c = base tile ID
+ ld b, TILEMAP_MON_PIC
+ hlcoord 12, 5
+ predef_jump CopyTileIDsFromList
+
+HoFDisplayPlayerStats:
+ SetEvent EVENT_HALL_OF_FAME_DEX_RATING
+ predef DisplayDexRating
+ hlcoord 0, 4
+ lb bc, 6, 10
+ call TextBoxBorder
+ hlcoord 5, 0
+ lb bc, 2, 9
+ call TextBoxBorder
+ hlcoord 7, 2
+ ld de, wPlayerName
+ call PlaceString
+ hlcoord 1, 6
+ ld de, HoFPlayTimeText
+ call PlaceString
+ hlcoord 5, 7
+ ld de, wPlayTimeHours
+ lb bc, 1, 3
+ call PrintNumber
+ ld [hl], $6d
+ inc hl
+ ld de, wPlayTimeMinutes
+ lb bc, LEADING_ZEROES | 1, 2
+ call PrintNumber
+ hlcoord 1, 9
+ ld de, HoFMoneyText
+ call PlaceString
+ hlcoord 4, 10
+ ld de, wPlayerMoney
+ ld c, $a3
+ call PrintBCDNumber
+ ld hl, DexSeenOwnedText
+ call HoFPrintTextAndDelay
+ ld hl, DexRatingText
+ call HoFPrintTextAndDelay
+ ld hl, wDexRatingText
+
+HoFPrintTextAndDelay:
+ call PrintText
+ ld c, 120
+ jp DelayFrames
+
+HoFPlayTimeText:
+ db "PLAY TIME@"
+
+HoFMoneyText:
+ db "MONEY@"
+
+DexSeenOwnedText:
+ text_far _DexSeenOwnedText
+ text_end
+
+DexRatingText:
+ text_far _DexRatingText
+ text_end
+
+HoFRecordMonInfo:
+ ld hl, wHallOfFame
+ ld bc, HOF_MON
+ ld a, [wHoFPartyMonIndex]
+ call AddNTimes
+ ld a, [wHoFMonSpecies]
+ ld [hli], a
+ ld a, [wHoFMonLevel]
+ ld [hli], a
+ ld e, l
+ ld d, h
+ ld hl, wcd6d
+ ld bc, NAME_LENGTH
+ jp CopyData
+
+HoFFadeOutScreenAndMusic:
+ ld a, 10
+ ld [wAudioFadeOutCounterReloadValue], a
+ ld [wAudioFadeOutCounter], a
+ ld a, $ff
+ ld [wAudioFadeOutControl], a
+ jp GBFadeOutToWhite
diff --git a/engine/movie/intro.asm b/engine/movie/intro.asm
new file mode 100755
index 00000000..9165113f
--- /dev/null
+++ b/engine/movie/intro.asm
@@ -0,0 +1,157 @@
+ const_def -1
+ const MOVE_NIDORINO_RIGHT
+ const MOVE_GENGAR_RIGHT
+ const MOVE_GENGAR_LEFT
+
+ANIMATION_END EQU 80
+
+PlayIntro:
+ xor a
+ ldh [hJoyHeld], a
+ inc a
+ ldh [hAutoBGTransferEnabled], a
+ call PlayShootingStar
+ callfar PlayIntroScene
+ xor a
+ ldh [hSCX], a
+ ldh [hAutoBGTransferEnabled], a
+ call ClearSprites
+ call DelayFrame
+ ret
+
+InitIntroNidorinoOAM:
+ ld hl, wOAMBuffer
+ ld d, 0
+.loop
+ push bc
+ ld a, [wBaseCoordY]
+ ld e, a
+.innerLoop
+ ld a, e
+ add 8
+ ld e, a
+ ld [hli], a ; Y
+ ld a, [wBaseCoordX]
+ ld [hli], a ; X
+ ld a, d
+ ld [hli], a ; tile
+ ld a, OAM_BEHIND_BG
+ ld [hli], a ; attributes
+ inc d
+ dec c
+ jr nz, .innerLoop
+ ld a, [wBaseCoordX]
+ add 8
+ ld [wBaseCoordX], a
+ pop bc
+ dec b
+ jr nz, .loop
+ ret
+
+IntroClearScreen:
+ ld hl, vBGMap1
+ ld bc, BG_MAP_WIDTH * SCREEN_HEIGHT
+ jr IntroClearCommon
+
+IntroClearMiddleOfScreen:
+; clear the area of the tile map between the black bars on the top and bottom
+ hlcoord 0, 4
+ ld bc, SCREEN_WIDTH * 10
+
+IntroClearCommon:
+ ld [hl], 0
+ inc hl
+ dec bc
+ ld a, b
+ or c
+ jr nz, IntroClearCommon
+ ret
+
+IntroPlaceBlackTiles:
+ ld a, 1
+.loop
+ ld [hli], a
+ dec c
+ jr nz, .loop
+ ret
+
+CopyTileIDsFromList_ZeroBaseTileID:
+ ld c, 0
+ predef_jump CopyTileIDsFromList
+
+PlayShootingStar:
+ ld b, SET_PAL_GAME_FREAK_INTRO
+ call RunPaletteCommand
+ farcall LoadCopyrightAndTextBoxTiles
+ ldPal a, BLACK, DARK_GRAY, LIGHT_GRAY, WHITE
+ ldh [rBGP], a
+ call UpdateGBCPal_BGP
+ ld c, 180
+ call DelayFrames
+ call ClearScreen
+ call DisableLCD
+ xor a
+ ld [wCurOpponent], a
+ call IntroDrawBlackBars
+; write the black and white tiles
+ ld hl, vChars2
+ ld bc, $10
+ xor a
+ call FillMemory
+ ld hl, vChars2 + $10
+ ld bc, $10
+ ld a, $ff
+ call FillMemory
+; copy gamefreak logo and others
+ ld hl, GameFreakIntro
+ ld de, vChars2 + $600
+ ld bc, GameFreakIntroEnd - GameFreakIntro
+ ld a, BANK(GameFreakIntro)
+ call FarCopyData
+ ld hl, GameFreakIntro
+ ld de, vChars1
+ ld bc, GameFreakIntroEnd - GameFreakIntro
+ ld a, BANK(GameFreakIntro)
+ call FarCopyData
+
+ call EnableLCD
+ ld hl, rLCDC
+ res 5, [hl]
+ set 3, [hl]
+ ld c, 64
+ call DelayFrames
+ farcall AnimateShootingStar
+ push af
+ pop af
+ jr c, .next ; skip the delay if the user interrupted the animation
+ ld c, 40
+ call DelayFrames
+.next
+ call IntroClearMiddleOfScreen
+ call ClearSprites
+ jp Delay3
+
+IntroDrawBlackBars:
+; clear the screen and draw black bars on the top and bottom
+ call IntroClearScreen
+ hlcoord 0, 0
+ ld c, SCREEN_WIDTH * 4
+ call IntroPlaceBlackTiles
+ hlcoord 0, 14
+ ld c, SCREEN_WIDTH * 4
+ call IntroPlaceBlackTiles
+ ld hl, vBGMap1
+ ld c, BG_MAP_WIDTH * 4
+ call IntroPlaceBlackTiles
+ hlbgcoord 0, 14, vBGMap1
+ ld c, BG_MAP_WIDTH * 4
+ jp IntroPlaceBlackTiles
+
+EmptyFunc2:
+ ret
+
+GameFreakIntro:
+ INCBIN "gfx/splash/gamefreak_presents.2bpp"
+ INCBIN "gfx/splash/gamefreak_logo.2bpp"
+ ds 16, $00 ; blank tile
+GameFreakIntroEnd:
diff --git a/engine/movie/oak_speech/clear_save.asm b/engine/movie/oak_speech/clear_save.asm
new file mode 100755
index 00000000..2dd5f4a7
--- /dev/null
+++ b/engine/movie/oak_speech/clear_save.asm
@@ -0,0 +1,27 @@
+DoClearSaveDialogue:
+ call ClearScreen
+ call RunDefaultPaletteCommand
+ call LoadFontTilePatterns
+ call LoadTextBoxTilePatterns
+ ld hl, ClearSaveDataText
+ call PrintText
+ ld a, B_BUTTON
+ ld [wJoyIgnore], a
+ hlcoord 14, 7
+ lb bc, 8, 15
+ ld a, NO_YES_MENU
+ ld [wTwoOptionMenuID], a
+ ld a, TWO_OPTION_MENU
+ ld [wTextBoxID], a
+ call DisplayTextBoxID
+ ld a, 0
+ ld [wJoyIgnore], a
+ ld a, [wCurrentMenuItem]
+ and a
+ jp z, Init
+ farcall ClearSAV
+ jp Init
+
+ClearSaveDataText:
+ text_far _ClearSaveDataText
+ text_end
diff --git a/engine/movie/oak_speech/init_player_data.asm b/engine/movie/oak_speech/init_player_data.asm
new file mode 100644
index 00000000..d6745daf
--- /dev/null
+++ b/engine/movie/oak_speech/init_player_data.asm
@@ -0,0 +1,60 @@
+InitPlayerData:
+InitPlayerData2:
+
+ call Random
+ ldh a, [hRandomSub]
+ ld [wPlayerID], a
+
+ call Random
+ ldh a, [hRandomAdd]
+ ld [wPlayerID + 1], a
+
+ ld a, $ff
+ ld [wUnusedD71B], a
+
+ ld a, 90 ; initialize happiness to 90
+ ld [wPikachuHappiness], a
+ ld a, $80
+ ld [wPikachuMood], a ; initialize mood
+
+ ld hl, wPartyCount
+ call InitializeEmptyList
+ ld hl, wNumInBox
+ call InitializeEmptyList
+ ld hl, wNumBagItems
+ call InitializeEmptyList
+ ld hl, wNumBoxItems
+ call InitializeEmptyList
+
+START_MONEY EQU $3000
+ ld hl, wPlayerMoney + 1
+ ld a, HIGH(START_MONEY)
+ ld [hld], a
+ xor a ; LOW(START_MONEY)
+ ld [hli], a
+ inc hl
+ ld [hl], a
+
+ ld [wMonDataLocation], a
+
+ ld hl, wObtainedBadges
+ ld [hli], a
+
+ ld [hl], a
+
+ ld hl, wPlayerCoins
+ ld [hli], a
+ ld [hl], a
+
+ ld hl, wGameProgressFlags
+ ld bc, wGameProgressFlagsEnd - wGameProgressFlags
+ call FillMemory ; clear all game progress flags
+
+ jp InitializeMissableObjectsFlags
+
+InitializeEmptyList:
+ xor a ; count
+ ld [hli], a
+ dec a ; terminator
+ ld [hl], a
+ ret
diff --git a/engine/movie/oak_speech/oak_speech.asm b/engine/movie/oak_speech/oak_speech.asm
new file mode 100755
index 00000000..1a327def
--- /dev/null
+++ b/engine/movie/oak_speech/oak_speech.asm
@@ -0,0 +1,244 @@
+SetDefaultNames:
+ ld a, [wLetterPrintingDelayFlags]
+ push af
+ ld a, [wOptions]
+ push af
+ ld a, [wd732]
+ push af
+ ld a, [wPrinterSettings]
+ push af
+ ld hl, wPlayerName
+ ld bc, wBoxDataEnd - wPlayerName
+ xor a
+ call FillMemory
+ ld hl, wSpriteDataStart
+ ld bc, wSpriteDataEnd - wSpriteDataStart
+ xor a
+ call FillMemory
+ xor a
+ ld [wSurfingMinigameHiScore], a
+ ld [wSurfingMinigameHiScore + 1], a
+ ld [wSurfingMinigameHiScore + 2], a
+ pop af
+ ld [wPrinterSettings], a
+ pop af
+ ld [wd732], a
+ pop af
+ ld [wOptions], a
+ pop af
+ ld [wLetterPrintingDelayFlags], a
+ ld a, [wOptionsInitialized]
+ and a
+ call z, InitOptions
+ ld hl, NintenText
+ ld de, wPlayerName
+ ld bc, NAME_LENGTH
+ call CopyData
+ ld hl, SonyText
+ ld de, wRivalName
+ ld bc, NAME_LENGTH
+ call CopyData ; rip optimizations
+ ret
+
+OakSpeech:
+ call StopAllMusic ; stop music
+ ld a, BANK(Music_Routes2)
+ ld c, a
+ ld a, MUSIC_ROUTES2
+ call PlayMusic
+ call ClearScreen
+ call LoadTextBoxTilePatterns
+ call SetDefaultNames
+ predef InitPlayerData2
+ ld hl, wNumBoxItems
+ ld a, POTION
+ ld [wcf91], a
+ ld a, 1
+ ld [wItemQuantity], a
+ call AddItemToInventory ; give one potion
+ ld a, [wDefaultMap]
+ ld [wDestinationMap], a
+ call SpecialWarpIn
+ xor a
+ ldh [hTilesetType], a
+ ld a, [wd732]
+ bit 1, a ; possibly a debug mode bit
+ jp nz, .skipChoosingNames
+ ld de, ProfOakPic
+ lb bc, BANK(ProfOakPic), $00
+ call IntroDisplayPicCenteredOrUpperRight
+ call FadeInIntroPic
+ ld hl, OakSpeechText1
+ call PrintText
+ call GBFadeOutToWhite
+ call ClearScreen
+ ld a, PIKACHU
+ ld [wd0b5], a
+ ld [wcf91], a
+ call GetMonHeader
+ hlcoord 6, 4
+ call LoadFlippedFrontSpriteByMonIndex
+ call MovePicLeft
+ ld hl, OakSpeechText2
+ call PrintText
+ call GBFadeOutToWhite
+ call ClearScreen
+ ld de, RedPicFront
+ lb bc, BANK(RedPicFront), $00
+ call IntroDisplayPicCenteredOrUpperRight
+ call MovePicLeft
+ ld hl, IntroducePlayerText
+ call PrintText
+ call ChoosePlayerName
+ call GBFadeOutToWhite
+ call ClearScreen
+ ld de, Rival1Pic
+ lb bc, BANK(Rival1Pic), $00
+ call IntroDisplayPicCenteredOrUpperRight
+ call FadeInIntroPic
+ ld hl, IntroduceRivalText
+ call PrintText
+ call ChooseRivalName
+.skipChoosingNames
+ call GBFadeOutToWhite
+ call ClearScreen
+ ld de, RedPicFront
+ lb bc, BANK(RedPicFront), $00
+ call IntroDisplayPicCenteredOrUpperRight
+ call GBFadeInFromWhite
+ ld a, [wd72d]
+ and a
+ jr nz, .next
+ ld hl, OakSpeechText3
+ call PrintText
+.next
+ ldh a, [hLoadedROMBank]
+ push af
+ ld a, SFX_SHRINK
+ call PlaySound
+ pop af
+ call BankswitchCommon
+ ld c, 4
+ call DelayFrames
+ ld hl, vSprites
+ ld de, RedSprite
+ ld b, BANK(RedSprite)
+ ld c, $0C
+ call CopyVideoData
+ ld de, ShrinkPic1
+ lb bc, BANK(ShrinkPic1), $00
+ call IntroDisplayPicCenteredOrUpperRight
+ ld c, 4
+ call DelayFrames
+ ld de, ShrinkPic2
+ lb bc, BANK(ShrinkPic2), $00
+ call IntroDisplayPicCenteredOrUpperRight
+ call ResetPlayerSpriteData
+ ldh a, [hLoadedROMBank]
+ push af
+ ld a, BANK(Music_PalletTown)
+ ld [wAudioROMBank], a
+ ld [wAudioSavedROMBank], a
+ ld a, 10
+ ld [wAudioFadeOutControl], a
+ call StopAllMusic
+ pop af
+ call BankswitchCommon
+ ld c, 20
+ call DelayFrames
+ hlcoord 6, 5
+ lb bc, 7, 7
+ call ClearScreenArea
+ call LoadTextBoxTilePatterns
+ ld a, 1
+ ld [wUpdateSpritesEnabled], a
+ ld c, 50
+ call DelayFrames
+ call GBFadeOutToWhite
+ call ClearScreen ; rip more tail-end optimizations
+ ret
+
+OakSpeechText1:
+ text_far _OakSpeechText1
+ text_end
+OakSpeechText2:
+ text_far _OakSpeechText2A
+ sound_cry_pikachu
+ text_far _OakSpeechText2B
+ text_end
+IntroducePlayerText:
+ text_far _IntroducePlayerText
+ text_end
+IntroduceRivalText:
+ text_far _IntroduceRivalText
+ text_end
+OakSpeechText3:
+ text_far _OakSpeechText3
+ text_end
+
+FadeInIntroPic:
+ ld hl, IntroFadePalettes
+ ld b, 6
+.next
+ ld a, [hli]
+ ldh [rBGP], a
+ call UpdateGBCPal_BGP
+ ld c, 10
+ call DelayFrames
+ dec b
+ jr nz, .next
+ ret
+
+IntroFadePalettes:
+ db %01010100
+ db %10101000
+ db %11111100
+ db %11111000
+ db %11110100
+ db %11100100
+
+MovePicLeft:
+ ld a, 119
+ ldh [rWX], a
+ call DelayFrame
+
+ ld a, %11100100
+ ldh [rBGP], a
+ call UpdateGBCPal_BGP
+.next
+ call DelayFrame
+ ldh a, [rWX]
+ sub 8
+ cp $FF
+ ret z
+ ldh [rWX], a
+ jr .next
+
+DisplayPicCenteredOrUpperRight:
+ call GetPredefRegisters
+IntroDisplayPicCenteredOrUpperRight:
+; b = bank
+; de = address of compressed pic
+; c: 0 = centred, non-zero = upper-right
+ push bc
+ ld a, b
+ call UncompressSpriteFromDE
+ ld a, $0
+ call SwitchSRAMBankAndLatchClockData
+ ld hl, sSpriteBuffer1
+ ld de, sSpriteBuffer0
+ ld bc, $310
+ call CopyData
+ call PrepareRTCDataAndDisableSRAM
+ ld de, vFrontPic
+ call InterlaceMergeSpriteBuffers
+ pop bc
+ ld a, c
+ and a
+ hlcoord 15, 1
+ jr nz, .next
+ hlcoord 6, 4
+.next
+ xor a
+ ldh [hStartTileID], a
+ predef_jump CopyUncompressedPicToTilemap
diff --git a/engine/movie/oak_speech/oak_speech2.asm b/engine/movie/oak_speech/oak_speech2.asm
new file mode 100755
index 00000000..af31665b
--- /dev/null
+++ b/engine/movie/oak_speech/oak_speech2.asm
@@ -0,0 +1,219 @@
+ChoosePlayerName:
+ call OakSpeechSlidePicRight
+ ld de, DefaultNamesPlayer
+ call DisplayIntroNameTextBox
+ ld a, [wCurrentMenuItem]
+ and a
+ jr z, .customName
+ ld hl, DefaultNamesPlayerList
+ call GetDefaultName
+ ld de, wPlayerName
+ call OakSpeechSlidePicLeft
+ jr .done
+.customName
+ ld hl, wPlayerName
+ xor a ; NAME_PLAYER_SCREEN
+ ld [wNamingScreenType], a
+ call DisplayNamingScreen
+ ld a, [wcf4b]
+ cp "@"
+ jr z, .customName
+ call ClearScreen
+ call Delay3
+ ld de, RedPicFront
+ ld b, BANK(RedPicFront)
+ call IntroDisplayPicCenteredOrUpperRight
+.done
+ ld hl, YourNameIsText
+ jp PrintText
+
+YourNameIsText:
+ text_far _YourNameIsText
+ text_end
+
+ChooseRivalName:
+ call OakSpeechSlidePicRight
+ ld de, DefaultNamesRival
+ call DisplayIntroNameTextBox
+ ld a, [wCurrentMenuItem]
+ and a
+ jr z, .customName
+ ld hl, DefaultNamesRivalList
+ call GetDefaultName
+ ld de, wRivalName
+ call OakSpeechSlidePicLeft
+ jr .done
+.customName
+ ld hl, wRivalName
+ ld a, NAME_RIVAL_SCREEN
+ ld [wNamingScreenType], a
+ call DisplayNamingScreen
+ ld a, [wcf4b]
+ cp "@"
+ jr z, .customName
+ call ClearScreen
+ call Delay3
+ ld de, Rival1Pic
+ ld b, $13
+ call IntroDisplayPicCenteredOrUpperRight
+.done
+ ld hl, HisNameIsText
+ jp PrintText
+
+HisNameIsText:
+ text_far _HisNameIsText
+ text_end
+
+OakSpeechSlidePicLeft:
+ push de
+ hlcoord 0, 0
+ lb bc, 12, 11
+ call ClearScreenArea ; clear the name list text box
+ ld c, 10
+ call DelayFrames
+ pop de
+ ld hl, wcd6d
+ ld bc, NAME_LENGTH
+ call CopyData
+ call Delay3
+ hlcoord 12, 4
+ lb de, 6, 6 * SCREEN_WIDTH + 5
+ ld a, $ff
+ jr OakSpeechSlidePicCommon
+
+OakSpeechSlidePicRight:
+ hlcoord 5, 4
+ lb de, 6, 6 * SCREEN_WIDTH + 5
+ xor a
+
+OakSpeechSlidePicCommon:
+ push hl
+ push de
+ push bc
+ ldh [hSlideDirection], a
+ ld a, d
+ ldh [hSlideAmount], a
+ ld a, e
+ ldh [hSlidingRegionSize], a
+ ld c, a
+ ldh a, [hSlideDirection]
+ and a
+ jr nz, .next
+; If sliding right, point hl to the end of the pic's tiles.
+ ld d, 0
+ add hl, de
+.next
+ ld d, h
+ ld e, l
+.loop
+ xor a
+ ldh [hAutoBGTransferEnabled], a
+ ldh [hAutoBGTransferPortion], a
+ ldh a, [hSlideDirection]
+ and a
+ jr nz, .slideLeft
+; sliding right
+ ld a, [hli]
+ ld [hld], a
+ dec hl
+ jr .next2
+.slideLeft
+ ld a, [hld]
+ ld [hli], a
+ inc hl
+.next2
+ dec c
+ jr nz, .loop
+ ldh a, [hSlideDirection]
+ and a
+ jr z, .next3
+; If sliding left, we need to zero the last tile in the pic (there is no need
+; to take a corresponding action when sliding right because hl initially points
+; to a 0 tile in that case).
+ dec hl
+ xor a
+ ld [hl], a
+.next3
+ ld a, 1
+ ldh [hAutoBGTransferEnabled], a
+ call Delay3
+ ldh a, [hSlidingRegionSize]
+ ld c, a
+ ld h, d
+ ld l, e
+ ldh a, [hSlideDirection]
+ and a
+ jr nz, .slideLeft2
+ inc hl
+ jr .next4
+.slideLeft2
+ dec hl
+.next4
+ ld d, h
+ ld e, l
+ ldh a, [hSlideAmount]
+ dec a
+ ldh [hSlideAmount], a
+ jr nz, .loop
+ pop bc
+ pop de
+ pop hl
+ ret
+
+DisplayIntroNameTextBox:
+ push de
+ hlcoord 0, 0
+ lb bc, 10, 9
+ call TextBoxBorder
+ hlcoord 3, 0
+ ld de, .namestring
+ call PlaceString
+ pop de
+ hlcoord 2, 2
+ call PlaceString
+ call UpdateSprites
+ xor a
+ ld [wCurrentMenuItem], a
+ ld [wLastMenuItem], a
+ inc a
+ ld [wTopMenuItemX], a
+ ld [wMenuWatchedKeys], a ; A_BUTTON
+ inc a
+ ld [wTopMenuItemY], a
+ inc a
+ ld [wMaxMenuItem], a
+ jp HandleMenuInput
+
+.namestring
+ db "NAME@"
+
+INCLUDE "data/player_names.asm"
+
+GetDefaultName:
+; a = name index
+; hl = name list
+ ld b, a
+ ld c, 0
+.loop
+ ld d, h
+ ld e, l
+.innerLoop
+ ld a, [hli]
+ cp "@"
+ jr nz, .innerLoop
+ ld a, b
+ cp c
+ jr z, .foundName
+ inc c
+ jr .loop
+.foundName
+ ld h, d
+ ld l, e
+ ld de, wcd6d
+ ld bc, $14
+ jp CopyData
+
+INCLUDE "data/player_names_list.asm"
+
+LinkMenuEmptyText:
+ text_end
diff --git a/engine/movie/splash.asm b/engine/movie/splash.asm
new file mode 100755
index 00000000..4cb0a59a
--- /dev/null
+++ b/engine/movie/splash.asm
@@ -0,0 +1,259 @@
+LoadShootingStarGraphics:
+ ld a, $f9
+ ldh [rOBP0], a
+ ld a, $a4
+ ldh [rOBP1], a
+ call UpdateGBCPal_OBP0
+ call UpdateGBCPal_OBP1
+ ld de, AnimationTileset2 tile 3 ; star tile (top left quadrant)
+ ld hl, vChars1 tile $20
+ lb bc, BANK(AnimationTileset2), $01
+ call CopyVideoData
+ ld de, AnimationTileset2 tile 19 ; star tile (bottom left quadrant)
+ ld hl, vChars1 tile $21
+ lb bc, BANK(AnimationTileset2), 1
+ call CopyVideoData
+ ld de, FallingStar
+ ld hl, vChars1 tile $22
+ lb bc, BANK(FallingStar), (FallingStarEnd - FallingStar) / $10
+ call CopyVideoData
+ ld hl, GameFreakLogoOAMData
+ ld de, wOAMBuffer + $60
+ ld bc, GameFreakLogoOAMDataEnd - GameFreakLogoOAMData
+ call CopyData
+ ld hl, GameFreakShootingStarOAMData
+ ld de, wOAMBuffer
+ ld bc, GameFreakShootingStarOAMDataEnd - GameFreakShootingStarOAMData
+ jp CopyData
+
+AnimateShootingStar:
+ call LoadShootingStarGraphics
+ ld a, SFX_SHOOTING_STAR
+ call PlaySound
+
+; Move the big star down and left across the screen.
+ ld hl, wOAMBuffer
+ lb bc, $a0, $4
+.bigStarLoop
+ push hl
+ push bc
+.bigStarInnerLoop
+ ld a, [hl] ; Y
+ add 4
+ ld [hli], a
+ ld a, [hl] ; X
+ add -4
+ ld [hli], a
+ inc hl
+ inc hl
+ dec c
+ jr nz, .bigStarInnerLoop
+ ld c, 1
+ call CheckForUserInterruption
+ pop bc
+ pop hl
+ ret c
+ ld a, [hl]
+ cp 80
+ jr nz, .next
+ jr .bigStarLoop
+.next
+ cp b
+ jr nz, .bigStarLoop
+
+; Clear big star OAM.
+ ld hl, wOAMBuffer
+ ld c, 4
+ ld de, 4
+.clearOAMLoop
+ ld [hl], 160
+ add hl, de
+ dec c
+ jr nz, .clearOAMLoop
+
+; Make Gamefreak logo flash.
+ ld b, 3
+.flashLogoLoop
+ ld hl, rOBP0
+ rrc [hl]
+ rrc [hl]
+ call UpdateGBCPal_OBP0
+ ld c, 10
+ call CheckForUserInterruption
+ ret c
+ dec b
+ jr nz, .flashLogoLoop
+
+; Copy 24 instances of the small stars OAM data.
+; Note that their coordinates put them off-screen.
+ ld de, wOAMBuffer
+ ld a, 24
+.initSmallStarsOAMLoop
+ push af
+ ld hl, SmallStarsOAM
+ ld bc, SmallStarsOAMEnd - SmallStarsOAM
+ call CopyData
+ pop af
+ dec a
+ jr nz, .initSmallStarsOAMLoop
+
+; Animate the small stars falling from the Gamefreak logo.
+ xor a
+ ld [wMoveDownSmallStarsOAMCount], a
+ ld hl, SmallStarsWaveCoordsPointerTable
+ ld c, 6
+.smallStarsLoop
+ ld a, [hli]
+ ld e, a
+ ld a, [hli]
+ ld d, a
+ push bc
+ push hl
+ ld hl, wOAMBuffer + $50
+ ld c, 4
+.smallStarsInnerLoop ; introduce new wave of 4 small stars OAM entries
+ ld a, [de]
+ cp -1
+ jr z, .next2
+ ld [hli], a ; Y
+ inc de
+ ld a, [de]
+ ld [hli], a ; X
+ inc de
+ inc hl
+ push bc
+ ld a, [de]
+ ld b, a
+ ld a, [hl]
+ and $f0
+ or b
+ ld [hl], a
+ inc de
+ pop bc
+ inc hl
+ dec c
+ jr nz, .smallStarsInnerLoop
+ ld a, [wMoveDownSmallStarsOAMCount]
+ cp 24
+ jr z, .next2
+ add 6 ; should be 4, but the extra 2 aren't visible on screen
+ ld [wMoveDownSmallStarsOAMCount], a
+.next2
+ call MoveDownSmallStars
+ push af
+
+; shift the existing OAM entries down to make room for the next wave
+ ld hl, wOAMBuffer + $10
+ ld de, wOAMBuffer
+ ld bc, $50
+ call CopyData
+
+ pop af
+ pop hl
+ pop bc
+ ret c
+ dec c
+ jr nz, .smallStarsLoop
+ and a
+ ret
+
+SmallStarsOAM:
+ dbsprite 0, 0, 0, 0, $A2, OAM_BEHIND_BG | OAM_OBP1
+SmallStarsOAMEnd:
+
+SmallStarsWaveCoordsPointerTable:
+ dw SmallStarsWave1Coords
+ dw SmallStarsWave2Coords
+ dw SmallStarsWave3Coords
+ dw SmallStarsWave4Coords
+ dw SmallStarsEmptyWave
+ dw SmallStarsEmptyWave
+
+; The stars that fall from the Gamefreak logo come in 4 waves of 4 OAM entries.
+; These arrays contain the Y and X coordinates of each OAM entry.
+
+SmallStarsWave1Coords:
+ db $68, $30
+ db $05, $68
+ db $40, $05
+ db $68, $58
+ db $04, $68
+ db $78, $07
+SmallStarsWave2Coords:
+ db $68, $38
+ db $05, $68
+ db $48, $06
+ db $68, $60
+ db $04, $68
+ db $70, $07
+SmallStarsWave3Coords:
+ db $68, $34
+ db $05, $68
+ db $4c, $06
+ db $68, $54
+ db $06, $68
+ db $64, $07
+SmallStarsWave4Coords:
+ db $68, $3c
+ db $05, $68
+ db $5c, $04
+ db $68, $6c
+ db $07, $68
+ db $74, $07
+SmallStarsEmptyWave:
+ db -1 ; end
+
+MoveDownSmallStars:
+ ld b, 8
+.loop
+ ld hl, wOAMBuffer + $5c
+ ld a, [wMoveDownSmallStarsOAMCount]
+ ld de, -4
+ ld c, a
+.innerLoop
+ inc [hl] ; Y
+ add hl, de
+ dec c
+ jr nz, .innerLoop
+; Toggle the palette so that the lower star in the small stars tile blinks in
+; and out.
+ ldh a, [rOBP1]
+ xor %10100000
+ ldh [rOBP1], a
+ call UpdateGBCPal_OBP1
+ ld c, 3
+ call CheckForUserInterruption
+ ret c
+ dec b
+ jr nz, .loop
+ ret
+
+GameFreakLogoOAMData:
+ dbsprite 10, 9, 0, 0, $8d, 0
+ dbsprite 11, 9, 0, 0, $8e, 0
+ dbsprite 10, 10, 0, 0, $8f, 0
+ dbsprite 11, 10, 0, 0, $90, 0
+ dbsprite 10, 11, 0, 0, $91, 0
+ dbsprite 11, 11, 0, 0, $92, 0
+ dbsprite 6, 12, 0, 0, $80, 0
+ dbsprite 7, 12, 0, 0, $81, 0
+ dbsprite 8, 12, 0, 0, $82, 0
+ dbsprite 9, 12, 0, 0, $83, 0
+ dbsprite 10, 12, 0, 0, $93, 0
+ dbsprite 11, 12, 0, 0, $84, 0
+ dbsprite 12, 12, 0, 0, $85, 0
+ dbsprite 13, 12, 0, 0, $83, 0
+ dbsprite 14, 12, 0, 0, $81, 0
+ dbsprite 15, 12, 0, 0, $86, 0
+GameFreakLogoOAMDataEnd:
+
+GameFreakShootingStarOAMData:
+ dbsprite 20, 0, 0, 0, $a0, OAM_OBP1 | %100
+ dbsprite 21, 0, 0, 0, $a0, OAM_OBP1 | OAM_HFLIP | %100
+ dbsprite 20, 1, 0, 0, $a1, OAM_OBP1 | %100
+ dbsprite 21, 1, 0, 0, $a1, OAM_OBP1 | OAM_HFLIP | %100
+GameFreakShootingStarOAMDataEnd:
+
+FallingStar:
+ INCBIN "gfx/splash/falling_star.2bpp"
+FallingStarEnd:
diff --git a/engine/movie/title.asm b/engine/movie/title.asm
new file mode 100755
index 00000000..1f2723a3
--- /dev/null
+++ b/engine/movie/title.asm
@@ -0,0 +1,370 @@
+SetDefaultNamesBeforeTitlescreen::
+ ld hl, NintenText
+ ld de, wPlayerName
+ call CopyFixedLengthText
+ ld hl, SonyText
+ ld de, wRivalName
+ call CopyFixedLengthText
+ xor a
+ ldh [hWY], a
+ ld [wLetterPrintingDelayFlags], a
+ ld hl, wd732
+ ld [hli], a
+ ld [hli], a
+ ld [hl], a
+ ld a, BANK(Music_TitleScreen)
+ ld [wAudioROMBank], a
+ ld [wAudioSavedROMBank], a
+
+DisplayTitleScreen:
+ call GBPalWhiteOut
+ ld a, $1
+ ldh [hAutoBGTransferEnabled], a
+ xor a
+ ldh [hTilesetType], a
+ ldh [hSCX], a
+ ld a, $40
+ ldh [hSCY], a
+ ld a, $90
+ ldh [hWY], a
+ call ClearScreen
+ call DisableLCD
+ call LoadFontTilePatterns
+; todo: fix hl pointers
+ ld hl, NintendoCopyrightLogoGraphics
+ ld de, vTitleLogo tile $60
+ ld bc, 5 tiles
+ ld a, BANK(NintendoCopyrightLogoGraphics)
+ call FarCopyData
+ ld hl, NineTile
+ ld de, vTitleLogo tile $6e
+ ld bc, $10
+ ld a, BANK(NineTile)
+ call FarCopyData
+ ld hl, GamefreakLogoGraphics
+ ld de, vTitleLogo tile $65
+ ld bc, 9 tiles
+ ld a, BANK(GamefreakLogoGraphics)
+ call FarCopyData
+ callfar LoadYellowTitleScreenGFX
+ ld hl, vBGMap0
+ ld bc, (vBGMap1 tile $40) - vBGMap0
+ ld a, " "
+ call FillMemory
+ callfar TitleScreen_PlacePokemonLogo
+ call FillSpriteBuffer0WithAA
+ call .WriteCopyrightTiles
+ call SaveScreenTilesToBuffer2
+ call LoadScreenTilesFromBuffer2
+ call EnableLCD
+ callfar TitleScreen_PlacePikachu
+ ld a, HIGH(vBGMap0 + $300)
+ call TitleScreenCopyTileMapToVRAM
+ call SaveScreenTilesToBuffer1
+ ld a, $40
+ ldh [hWY], a
+ call LoadScreenTilesFromBuffer2
+ ld a, HIGH(vBGMap0)
+ call TitleScreenCopyTileMapToVRAM
+ ld b, SET_PAL_TITLE_SCREEN
+ call RunPaletteCommand
+ call GBPalNormal
+ ld a, %11100000
+ ldh [rOBP0], a
+ call UpdateGBCPal_OBP0
+
+; make pokemon logo bounce up and down
+ ld bc, hSCY ; background scroll Y
+ ld hl, .TitleScreenPokemonLogoYScrolls
+.bouncePokemonLogoLoop
+ ld a, [hli]
+ and a
+ jr z, .finishedBouncingPokemonLogo
+ ld d, a
+ cp -3
+ jr nz, .skipPlayingSound
+ ld a, SFX_INTRO_CRASH
+ call PlaySound
+.skipPlayingSound
+ ld a, [hli]
+ ld e, a
+ call .ScrollTitleScreenPokemonLogo
+ jr .bouncePokemonLogoLoop
+
+.TitleScreenPokemonLogoYScrolls:
+; Controls the bouncing effect of the Pokemon logo on the title screen
+ db -4,16 ; y scroll amount, number of times to scroll
+ db 3,4
+ db -3,4
+ db 2,2
+ db -2,2
+ db 1,2
+ db -1,2
+ db 0 ; terminate list with 0
+
+.ScrollTitleScreenPokemonLogo:
+; Scrolls the Pokemon logo on the title screen to create the bouncing effect
+; Scrolls d pixels e times
+ call DelayFrame
+ ld a, [bc] ; background scroll Y
+ add d
+ ld [bc], a
+ dec e
+ jr nz, .ScrollTitleScreenPokemonLogo
+ ret
+
+; place tiles for title screen copyright
+.WriteCopyrightTiles
+ hlcoord 2, 17
+ ld de, .tileScreenCopyrightTiles
+.titleScreenCopyrightTilesLoop
+ ld a, [de]
+ inc de
+ cp $ff
+ ret z
+ ld [hli], a
+ jr .titleScreenCopyrightTilesLoop
+
+.tileScreenCopyrightTiles
+ db $e0,$e1,$e2,$e3,$e1,$e2,$ee,$e5,$e6,$e7,$e8,$e9,$ea,$eb,$ec,$ed,$ff ; ©1995-1999 GAME FREAK inc.
+
+.finishedBouncingPokemonLogo
+ call LoadScreenTilesFromBuffer1
+ ld c, 36
+ call DelayFrames
+ ld a, SFX_INTRO_WHOOSH
+ call PlaySound
+
+; scroll game version in from the right
+ callfar TitleScreen_PlacePikaSpeechBubble
+ ld a, SCREEN_HEIGHT_PX
+ ldh [hWY], a
+ call Delay3
+ ld e, 0
+ call TitleScreen_PlayPikachuPCM
+ call WaitForSoundToFinish
+ call StopAllMusic
+ ld a, MUSIC_TITLE_SCREEN
+ ld [wNewSoundID], a
+ call PlaySound
+.loop
+ xor a
+ ld [wUnusedCC5B], a
+ ld [wTitleScreenScene], a
+ ld [wTitleScreenScene + 1], a
+ ld [wTitleScreenScene + 2], a
+ ld [wTitleScreenScene + 3], a
+ ld a, $f
+ ld [wTitleScreenScene + 4], a
+.titleScreenLoop
+ call IncrementResetCounter
+ jp c, .doTitlescreenReset
+ call DelayFrame
+ call JoypadLowSensitivity
+ ldh a, [hJoyHeld]
+ cp D_UP | SELECT | B_BUTTON
+ jr z, .go_to_main_menu
+ and A_BUTTON | START
+ jr nz, .go_to_main_menu
+ call DoTitleScreenFunction
+ jr .titleScreenLoop
+
+.go_to_main_menu
+ ld e, $a
+ call TitleScreen_PlayPikachuPCM
+ call GBPalWhiteOutWithDelay3
+ call ClearSprites
+ xor a
+ ldh [hWY], a
+ inc a
+ ldh [hAutoBGTransferEnabled], a
+ call ClearScreen
+ ld a, HIGH(vBGMap0)
+ call TitleScreenCopyTileMapToVRAM
+ ld a, HIGH(vBGMap1)
+ call TitleScreenCopyTileMapToVRAM
+ call Delay3
+ call LoadGBPal
+ ldh a, [hJoyHeld]
+ ld b, a
+ and D_UP | SELECT | B_BUTTON
+ cp D_UP | SELECT | B_BUTTON
+ jp z, .doClearSaveDialogue
+ jp MainMenu
+
+.asm_42f0
+; unreferenced
+ callfar PrinterDebug
+ jp .loop
+
+.asm_42fb
+; unreferenced
+ ld a, [wTitleScreenScene + 4]
+ inc a
+ cp $2a
+ jr c, .asm_4305
+ ld a, $f
+.asm_4305
+ ld [wTitleScreenScene + 4], a
+ ld e, a
+ callfar PlayPikachuSoundClip
+ xor a
+ ld [wTitleScreenScene + 2], a
+ ld [wTitleScreenScene + 3], a
+ jp .titleScreenLoop
+
+.doTitlescreenReset
+ ld [wAudioFadeOutControl], a
+ call StopAllMusic
+.audioFadeLoop
+ ld a, [wAudioFadeOutControl]
+ and a
+ jr nz, .audioFadeLoop
+ jp Init
+
+.doClearSaveDialogue
+ farjp DoClearSaveDialogue
+
+
+TitleScreenCopyTileMapToVRAM:
+ ldh [hAutoBGTransferDest + 1], a
+ jp Delay3
+
+LoadCopyrightAndTextBoxTiles:
+ xor a
+ ldh [hWY], a
+ call ClearScreen
+ call LoadTextBoxTilePatterns
+
+LoadCopyrightTiles:
+ ld de, NintendoCopyrightLogoGraphics
+ ld hl, vChars2 tile $60
+ lb bc, BANK(NintendoCopyrightLogoGraphics), (TextBoxGraphics + $10 - NintendoCopyrightLogoGraphics) / $10 ; bug: overflows into text box graphics and copies the "A" tile
+ call CopyVideoData
+ hlcoord 2, 7
+ ld de, CopyrightTextString
+ jp PlaceString
+
+CopyrightTextString:
+ db $60,$61,$62,$63,$61,$62,$7c,$7f,$65,$66,$67,$68,$69,$6a ; ©1995-1999 Nintendo
+ next $60,$61,$62,$63,$61,$62,$7c,$7f,$6b,$6c,$6d,$6e,$6f,$70,$71,$72 ; ©1995-1999 Creatures inc.
+ next $60,$61,$62,$63,$61,$62,$7c,$7f,$73,$74,$75,$76,$77,$78,$79,$7a,$7b ; ©1995-1999 GAME FREAK inc.
+ db "@"
+
+TitleScreen_PlayPikachuPCM:
+ callfar PlayPikachuSoundClip
+ ret
+
+DoTitleScreenFunction:
+ call .CheckTimer
+ ld a, [wTitleScreenScene]
+ ld e, a
+ 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 .Nop
+ dw .BlinkHalf
+ dw .BlinkWait
+ dw .BlinkWait
+ dw .BlinkClosed
+ dw .BlinkWait
+ dw .BlinkWait
+ dw .BlinkHalf
+ dw .BlinkWait
+ dw .BlinkWait
+ dw .BlinkOpen
+ dw .GoBackToStart
+
+.GoBackToStart:
+ xor a
+ ld [wTitleScreenScene], a
+.Nop
+ ret
+
+.BlinkOpen:
+ ld e, 0
+ jr .LoadBlinkFrame
+
+.BlinkHalf:
+ ld e, 4
+ jr .LoadBlinkFrame
+
+.BlinkClosed:
+ ld e, 8
+.LoadBlinkFrame:
+ ld hl, wOAMBuffer + 2
+ ld c, 8
+.loop
+ ld a, [hl]
+ and $f3
+ or e
+ ld [hli], a
+ inc hl
+ inc hl
+ inc hl
+ dec c
+ jr nz, .loop
+.BlinkWait:
+ ld hl, wTitleScreenScene
+ inc [hl]
+ ret
+
+.CheckTimer:
+ ld hl, wTitleScreenTimer
+ ld a, [hl]
+ inc [hl]
+ and a
+ jr z, .restart
+ cp $80
+ jr z, .restart
+ cp $90
+ ret nz
+.restart
+ ld a, $1
+ ld [wTitleScreenScene], a
+ ret
+
+; copy text of fixed length NAME_LENGTH (like player name, rival name, mon names, ...)
+CopyFixedLengthText:
+ ld bc, NAME_LENGTH
+ jp CopyData
+
+NintenText: db "NINTEN@"
+SonyText: db "SONY@"
+
+IncrementResetCounter:
+ ld hl, wTitleScreenScene + 2
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ inc de
+ ld a, d
+ cp $c
+ jr z, .doReset
+ ld [hl], d
+ dec hl
+ ld [hl], e
+ and a
+ ret
+
+.doReset
+ scf
+ ret
+
+FillSpriteBuffer0WithAA:
+ xor a
+ call SwitchSRAMBankAndLatchClockData
+ ld hl, sSpriteBuffer0
+ ld bc, $20
+ ld a, $aa
+ call FillMemory
+ call PrepareRTCDataAndDisableSRAM
+ ret
diff --git a/engine/movie/title2.asm b/engine/movie/title2.asm
new file mode 100755
index 00000000..df630b53
--- /dev/null
+++ b/engine/movie/title2.asm
@@ -0,0 +1,122 @@
+; Leftover of Red/Blue. Seemingly unused
+
+TitleScroll_WaitBall:
+; Wait around for the TitleBall animation to play out.
+; hi: speed
+; lo: duration
+ db $05, $05, 0
+
+TitleScroll_In:
+; Scroll a TitleMon in from the right.
+; hi: speed
+; lo: duration
+ db $a2, $94, $84, $63, $52, $31, $11, 0
+
+TitleScroll_Out:
+; Scroll a TitleMon out to the left.
+; hi: speed
+; lo: duration
+ db $12, $22, $32, $42, $52, $62, $83, $93, 0
+
+TitleScroll:
+ ld a, d
+
+ ld bc, TitleScroll_In
+ ld d, $88
+ ld e, 0 ; don't animate titleball
+
+ and a
+ jr nz, .ok
+
+ ld bc, TitleScroll_Out
+ ld d, $00
+ ld e, 0 ; don't animate titleball
+.ok
+
+_TitleScroll:
+ ld a, [bc]
+ and a
+ ret z
+
+ inc bc
+ push bc
+
+ ld b, a
+ and $f
+ ld c, a
+ ld a, b
+ and $f0
+ swap a
+ ld b, a
+
+.loop
+ ld h, d
+ ld l, $48
+ call .ScrollBetween
+
+ ld h, $00
+ ld l, $88
+ call .ScrollBetween
+
+ ld a, d
+ add b
+ ld d, a
+
+ call GetTitleBallY
+ dec c
+ jr nz, .loop
+
+ pop bc
+ jr _TitleScroll
+
+.ScrollBetween:
+.wait
+ ldh a, [rLY] ; rLY
+ cp l
+ jr nz, .wait
+
+ ld a, h
+ ldh [rSCX], a
+
+.wait2
+ ldh a, [rLY] ; rLY
+ cp h
+ jr z, .wait2
+ ret
+
+TitleBallYTable:
+; OBJ y-positions for the Poke Ball held by Red in the title screen.
+; This is really two 0-terminated lists. Initiated with an index of 1.
+ db 0, $71, $6f, $6e, $6d, $6c, $6d, $6e, $6f, $71, $74, 0
+
+TitleScreenAnimateBallIfStarterOut:
+; Animate the TitleBall if a starter just got scrolled out.
+ ld a, [wTitleScreenScene]
+ cp STARTER1
+ jr z, .ok
+ cp STARTER2
+ jr z, .ok
+ cp STARTER3
+ ret nz
+.ok
+ ld e, 1 ; animate titleball
+ ld bc, TitleScroll_WaitBall
+ ld d, 0
+ jp _TitleScroll
+
+GetTitleBallY:
+; Get position e from TitleBallYTable
+ push de
+ push hl
+ xor a
+ ld d, a
+ ld hl, TitleBallYTable
+ add hl, de
+ ld a, [hl]
+ pop hl
+ pop de
+ and a
+ ret z
+ ld [wOAMBuffer + $28], a
+ inc e
+ ret
diff --git a/engine/movie/trade.asm b/engine/movie/trade.asm
new file mode 100755
index 00000000..7be100e0
--- /dev/null
+++ b/engine/movie/trade.asm
@@ -0,0 +1,859 @@
+InternalClockTradeAnim:
+; Do the trading animation with the player's gameboy on the left.
+; In-game trades and internally clocked link cable trades use this.
+ ld a, [wTradedPlayerMonSpecies]
+ ld [wLeftGBMonSpecies], a
+ ld a, [wTradedEnemyMonSpecies]
+ ld [wRightGBMonSpecies], a
+ ld de, InternalClockTradeFuncSequence
+ jr TradeAnimCommon
+
+ExternalClockTradeAnim:
+; Do the trading animation with the player's gameboy on the right.
+; Externally clocked link cable trades use this.
+ ld a, [wTradedEnemyMonSpecies]
+ ld [wLeftGBMonSpecies], a
+ ld a, [wTradedPlayerMonSpecies]
+ ld [wRightGBMonSpecies], a
+ ld de, ExternalClockTradeFuncSequence
+
+TradeAnimCommon:
+ ld a, [wOptions]
+ push af
+ and %110000 ; preserve speaker options
+ ld [wOptions], a
+ ldh a, [hSCY]
+ push af
+ ldh a, [hSCX]
+ push af
+ xor a
+ ldh [hSCY], a
+ ldh [hSCX], a
+ push de
+.loop
+ pop de
+ ld a, [de]
+ cp $ff
+ jr z, .done
+ inc de
+ push de
+ ld hl, TradeFuncPointerTable
+ add a
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, .loop
+ push de
+ jp hl ; call trade func, which will return to the top of the loop
+.done
+ pop af
+ ldh [hSCX], a
+ pop af
+ ldh [hSCY], a
+ pop af
+ ld [wOptions], a
+ ret
+
+addtradefunc: MACRO
+\1TradeFunc::
+ dw \1
+ENDM
+
+tradefunc: MACRO
+ db (\1TradeFunc - TradeFuncPointerTable) / 2
+ENDM
+
+; The functions in the sequences below are executed in order by TradeFuncCommon.
+; They are from opposite perspectives. The external clock one makes use of
+; Trade_SwapNames to swap the player and enemy names for some functions.
+
+InternalClockTradeFuncSequence:
+ tradefunc LoadTradingGFXAndMonNames
+ tradefunc Trade_ShowPlayerMon
+ tradefunc Trade_DrawOpenEndOfLinkCable
+ tradefunc Trade_AnimateBallEnteringLinkCable
+ tradefunc Trade_AnimLeftToRight
+ tradefunc Trade_Delay100
+ tradefunc Trade_ShowClearedWindow
+ tradefunc PrintTradeWentToText
+ tradefunc PrintTradeForSendsText
+ tradefunc PrintTradeFarewellText
+ tradefunc Trade_AnimRightToLeft
+ tradefunc Trade_ShowClearedWindow
+ tradefunc Trade_DrawOpenEndOfLinkCable
+ tradefunc Trade_ShowEnemyMon
+ tradefunc Trade_Delay100
+ tradefunc Trade_Cleanup
+ db -1 ; end
+
+ExternalClockTradeFuncSequence:
+ tradefunc LoadTradingGFXAndMonNames
+ tradefunc Trade_ShowClearedWindow
+ tradefunc PrintTradeWillTradeText
+ tradefunc PrintTradeFarewellText
+ tradefunc Trade_SwapNames
+ tradefunc Trade_AnimLeftToRight
+ tradefunc Trade_SwapNames
+ tradefunc Trade_ShowClearedWindow
+ tradefunc Trade_DrawOpenEndOfLinkCable
+ tradefunc Trade_ShowEnemyMon
+ tradefunc Trade_SlideTextBoxOffScreen
+ tradefunc Trade_ShowPlayerMon
+ tradefunc Trade_DrawOpenEndOfLinkCable
+ tradefunc Trade_AnimateBallEnteringLinkCable
+ tradefunc Trade_SwapNames
+ tradefunc Trade_AnimRightToLeft
+ tradefunc Trade_SwapNames
+ tradefunc Trade_Delay100
+ tradefunc Trade_ShowClearedWindow
+ tradefunc PrintTradeWentToText
+ tradefunc Trade_Cleanup
+ db -1 ; end
+
+TradeFuncPointerTable:
+ addtradefunc LoadTradingGFXAndMonNames
+ addtradefunc Trade_ShowPlayerMon
+ addtradefunc Trade_DrawOpenEndOfLinkCable
+ addtradefunc Trade_AnimateBallEnteringLinkCable
+ addtradefunc Trade_ShowEnemyMon
+ addtradefunc Trade_AnimLeftToRight
+ addtradefunc Trade_AnimRightToLeft
+ addtradefunc Trade_Delay100
+ addtradefunc Trade_ShowClearedWindow
+ addtradefunc PrintTradeWentToText
+ addtradefunc PrintTradeForSendsText
+ addtradefunc PrintTradeFarewellText
+ addtradefunc PrintTradeTakeCareText
+ addtradefunc PrintTradeWillTradeText
+ addtradefunc Trade_Cleanup
+ addtradefunc Trade_SlideTextBoxOffScreen
+ addtradefunc Trade_SwapNames
+
+Trade_Delay100:
+ ld c, 100
+ jp DelayFrames
+
+Trade_CopyTileMapToVRAM:
+ ld a, $1
+ ldh [hAutoBGTransferEnabled], a
+ call Delay3
+ xor a
+ ldh [hAutoBGTransferEnabled], a
+ ret
+
+Trade_Delay80:
+ ld c, 80
+ jp DelayFrames
+
+Trade_ClearTileMap:
+ hlcoord 0, 0
+ ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
+ ld a, " "
+ jp FillMemory
+
+LoadTradingGFXAndMonNames:
+ call Trade_ClearTileMap
+ call DisableLCD
+ ld hl, TradingAnimationGraphics
+ ld de, vChars2 tile $31
+ ld bc, TradingAnimationGraphicsEnd - TradingAnimationGraphics
+ ld a, BANK(TradingAnimationGraphics)
+ call FarCopyData
+ ld hl, TradingAnimationGraphics2
+ ld de, vSprites tile $7c
+ ld bc, TradingAnimationGraphics2End - TradingAnimationGraphics2
+ ld a, BANK(TradingAnimationGraphics2)
+ call FarCopyData
+ ld hl, vBGMap0
+ ld bc, $800
+ ld a, " "
+ call FillMemory
+ call ClearSprites
+ ld a, $ff
+ ld [wUpdateSpritesEnabled], a
+ ld hl, wd730
+ set 6, [hl] ; turn on instant text printing
+ ld a, [wOnSGB]
+ and a
+ ld a, $e4 ; non-SGB OBP0
+ jr z, .next
+ ld a, $f0 ; SGB OBP0
+.next
+ ldh [rOBP0], a
+ call UpdateGBCPal_OBP0
+ call EnableLCD
+ xor a
+ ldh [hAutoBGTransferEnabled], a
+ ld a, [wTradedPlayerMonSpecies]
+ ld [wd11e], a
+ call GetMonName
+ ld hl, wcd6d
+ ld de, wcf4b
+ ld bc, NAME_LENGTH
+ call CopyData
+ ld a, [wTradedEnemyMonSpecies]
+ ld [wd11e], a
+ jp GetMonName
+
+Trade_LoadMonPartySpriteGfx:
+ ld a, %11010000
+ ldh [rOBP1], a
+ call UpdateGBCPal_OBP1
+ farjp LoadMonPartySpriteGfx
+
+Trade_SwapNames:
+ ld hl, wPlayerName
+ ld de, wBuffer
+ ld bc, NAME_LENGTH
+ call CopyData
+ ld hl, wLinkEnemyTrainerName
+ ld de, wPlayerName
+ ld bc, NAME_LENGTH
+ call CopyData
+ ld hl, wBuffer
+ ld de, wLinkEnemyTrainerName
+ ld bc, NAME_LENGTH
+ jp CopyData
+
+Trade_Cleanup:
+ xor a
+ call LoadGBPal
+ ld hl, wd730
+ res 6, [hl] ; turn off instant text printing
+ ret
+
+Trade_ShowPlayerMon:
+ ld a, %10101011
+ ldh [rLCDC], a
+ ld a, $50
+ ldh [hWY], a
+ ld a, $86
+ ldh [rWX], a
+ ldh [hSCX], a
+ xor a
+ ldh [hAutoBGTransferEnabled], a
+ hlcoord 4, 0
+ lb bc, 6, 10
+ call TextBoxBorder
+ call Trade_PrintPlayerMonInfoText
+ ld b, HIGH(vBGMap0)
+ call CopyScreenTileBufferToVRAM
+ call ClearScreen
+ ld a, [wTradedPlayerMonSpecies]
+ call Trade_LoadMonSprite
+ ld a, $7e
+.slideScreenLoop
+ push af
+ call DelayFrame
+ pop af
+ ldh [rWX], a
+ ldh [hSCX], a
+ dec a
+ dec a
+ and a
+ jr nz, .slideScreenLoop
+ call Trade_Delay80
+ ld a, TRADE_BALL_POOF_ANIM
+ call Trade_ShowAnimation
+ ld a, TRADE_BALL_DROP_ANIM
+ call Trade_ShowAnimation ; clears mon pic
+ ld a, [wTradedPlayerMonSpecies]
+ call PlayCry
+ xor a
+ ldh [hAutoBGTransferEnabled], a
+ ret
+
+Trade_DrawOpenEndOfLinkCable:
+ call Trade_ClearTileMap
+ ld b, HIGH(vBGMap0)
+ call CopyScreenTileBufferToVRAM
+ ld b, SET_PAL_GENERIC
+ call RunPaletteCommand
+
+; This function call is pointless. It just copies blank tiles to VRAM that was
+; already filled with blank tiles.
+ ld hl, vBGMap1 + $8c
+ call Trade_CopyCableTilesOffScreen
+
+ ld a, $a0
+ ldh [hSCX], a
+ call DelayFrame
+ ld a, %10001011
+ ldh [rLCDC], a
+ hlcoord 6, 2
+ ld b, TILEMAP_LINK_CABLE
+ call CopyTileIDsFromList_ZeroBaseTileID
+ call Trade_CopyTileMapToVRAM
+ ld a, SFX_HEAL_HP
+ call PlaySound
+ ld c, 20
+.loop
+ ldh a, [hSCX]
+ add 4
+ ldh [hSCX], a
+ dec c
+ jr nz, .loop
+ ret
+
+Trade_AnimateBallEnteringLinkCable:
+ ld a, TRADE_BALL_SHAKE_ANIM
+ call Trade_ShowAnimation
+ ld c, 10
+ call DelayFrames
+ ld a, %11100100
+ ldh [rOBP0], a
+ call UpdateGBCPal_OBP0
+ xor a
+ ld [wLinkCableAnimBulgeToggle], a
+ lb bc, $20, $60
+.moveBallInsideLinkCableLoop
+ push bc
+ xor a
+ ld de, Trade_BallInsideLinkCableOAM
+ call WriteOAMBlock
+ ld a, [wLinkCableAnimBulgeToggle]
+ xor $1
+ ld [wLinkCableAnimBulgeToggle], a
+ add $7e
+ ld hl, wOAMBuffer + $02
+ ld de, 4
+ ld c, e
+.cycleLinkCableBulgeTile
+ ld [hl], a
+ add hl, de
+ dec c
+ jr nz, .cycleLinkCableBulgeTile
+ call Delay3
+ pop bc
+ ld a, c
+ add $4
+ ld c, a
+ cp $a0
+ jr nc, .ballSpriteReachedEdgeOfScreen
+ ld a, SFX_TINK
+ call PlaySound
+ jr .moveBallInsideLinkCableLoop
+.ballSpriteReachedEdgeOfScreen
+ call ClearSprites
+ ld a, $1
+ ldh [hAutoBGTransferEnabled], a
+ call ClearScreen
+ ld b, $98
+ call CopyScreenTileBufferToVRAM
+ call Delay3
+ xor a
+ ldh [hAutoBGTransferEnabled], a
+ ret
+
+Trade_BallInsideLinkCableOAM:
+ dbsprite 0, 15, 0, 6, $7e, OAM_HFLIP
+ dbsprite 8, 15, 0, 6, $7e, OAM_HFLIP | OAM_VFLIP
+
+Trade_ShowEnemyMon:
+ ld a, TRADE_BALL_TILT_ANIM
+ call Trade_ShowAnimation
+ call Trade_ShowClearedWindow
+ hlcoord 4, 10
+ lb bc, 6, 10
+ call TextBoxBorder
+ call Trade_PrintEnemyMonInfoText
+ call Trade_CopyTileMapToVRAM
+ ld a, $1
+ ldh [hAutoBGTransferEnabled], a
+ ld a, [wTradedEnemyMonSpecies]
+ call Trade_LoadMonSprite
+ ld a, TRADE_BALL_POOF_ANIM
+ call Trade_ShowAnimation
+ ld a, $1
+ ldh [hAutoBGTransferEnabled], a
+ ld a, [wTradedEnemyMonSpecies]
+ call PlayCry
+ call Trade_Delay100
+ hlcoord 4, 10
+ lb bc, 8, 12
+ call ClearScreenArea
+ jp PrintTradeTakeCareText
+
+Trade_AnimLeftToRight:
+; Animates the mon moving from the left GB to the right one.
+ call Trade_InitGameboyTransferGfx
+ ld a, $1
+ ld [wTradedMonMovingRight], a
+ ld a, %11100100
+ ldh [rOBP0], a
+ call UpdateGBCPal_OBP0
+ ld a, $54
+ ld [wBaseCoordX], a
+ ld a, $1c
+ ld [wBaseCoordY], a
+ ld a, [wLeftGBMonSpecies]
+ ld [wMonPartySpriteSpecies], a
+ call Trade_WriteCircledMonOAM
+ call Trade_DrawLeftGameboy
+ call Trade_CopyTileMapToVRAM
+ call Trade_DrawCableAcrossScreen
+ ld hl, vBGMap1 + $8c
+ call Trade_CopyCableTilesOffScreen
+ ld b, $6
+ call Trade_AnimMonMoveHorizontal
+ ld a, $1
+ ldh [hAutoBGTransferEnabled], a
+ call Trade_DrawCableAcrossScreen
+ ld b, $4
+ call Trade_AnimMonMoveHorizontal
+ call Trade_DrawRightGameboy
+ ld b, $6
+ call Trade_AnimMonMoveHorizontal
+ xor a
+ ldh [hAutoBGTransferEnabled], a
+ call Trade_AnimMonMoveVertical
+ jp ClearSprites
+
+Trade_AnimRightToLeft:
+; Animates the mon moving from the right GB to the left one.
+ call Trade_InitGameboyTransferGfx
+ xor a
+ ld [wTradedMonMovingRight], a
+ ld a, $64
+ ld [wBaseCoordX], a
+ ld a, $44
+ ld [wBaseCoordY], a
+ ld a, [wRightGBMonSpecies]
+ ld [wMonPartySpriteSpecies], a
+ call Trade_WriteCircledMonOAM
+ call Trade_DrawRightGameboy
+ call Trade_CopyTileMapToVRAM
+ call Trade_DrawCableAcrossScreen
+ ld hl, vBGMap1 + $94
+ call Trade_CopyCableTilesOffScreen
+ call Trade_AnimMonMoveVertical
+ ld b, $6
+ call Trade_AnimMonMoveHorizontal
+ ld a, $1
+ ldh [hAutoBGTransferEnabled], a
+ call Trade_DrawCableAcrossScreen
+ ld b, $4
+ call Trade_AnimMonMoveHorizontal
+ call Trade_DrawLeftGameboy
+ ld b, $6
+ call Trade_AnimMonMoveHorizontal
+ xor a
+ ldh [hAutoBGTransferEnabled], a
+ jp ClearSprites
+
+Trade_InitGameboyTransferGfx:
+; Initialises the graphics for showing a mon moving between gameboys.
+ ld a, $1
+ ldh [hAutoBGTransferEnabled], a
+ call ClearScreen
+ ld b, SET_PAL_GENERIC
+ call RunPaletteCommand
+ xor a
+ ldh [hAutoBGTransferEnabled], a
+ call Trade_LoadMonPartySpriteGfx
+ call DelayFrame
+ ld a, %10101011
+ ldh [rLCDC], a
+ xor a
+ ldh [hSCX], a
+ ld a, $90
+ ldh [hWY], a
+ ret
+
+Trade_DrawLeftGameboy:
+ call Trade_ClearTileMap
+
+; draw link cable
+ hlcoord 11, 4
+ ld a, $5d
+ ld [hli], a
+ ld a, $5e
+ ld c, 8
+.loop
+ ld [hli], a
+ dec c
+ jr nz, .loop
+
+; draw gameboy pic
+ hlcoord 5, 3
+ ld b, TILEMAP_GAME_BOY
+ call CopyTileIDsFromList_ZeroBaseTileID
+
+; draw text box with player name below gameboy pic
+ hlcoord 4, 12
+ lb bc, 2, 7
+ call TextBoxBorder
+ hlcoord 5, 14
+ ld de, wPlayerName
+ call PlaceString
+
+ jp DelayFrame
+
+Trade_DrawRightGameboy:
+ call Trade_ClearTileMap
+
+; draw horizontal segment of link cable
+ hlcoord 0, 4
+ ld a, $5e
+ ld c, $e
+.loop
+ ld [hli], a
+ dec c
+ jr nz, .loop
+
+; draw vertical segment of link cable
+ ld a, $5f
+ ld [hl], a
+ ld de, SCREEN_WIDTH
+ add hl, de
+ ld a, $61
+ ld [hl], a
+ add hl, de
+ ld [hl], a
+ add hl, de
+ ld [hl], a
+ add hl, de
+ ld [hl], a
+ add hl, de
+ ld a, $60
+ ld [hld], a
+ ld a, $5d
+ ld [hl], a
+
+; draw gameboy pic
+ hlcoord 7, 8
+ ld b, TILEMAP_GAME_BOY
+ call CopyTileIDsFromList_ZeroBaseTileID
+
+; draw text box with enemy name above link cable
+ hlcoord 6, 0
+ lb bc, 2, 7
+ call TextBoxBorder
+ hlcoord 7, 2
+ ld de, wLinkEnemyTrainerName
+ call PlaceString
+
+ jp DelayFrame
+
+Trade_DrawCableAcrossScreen:
+; Draws the link cable across the screen.
+ call Trade_ClearTileMap
+ hlcoord 0, 4
+ ld a, $5e
+ ld c, SCREEN_WIDTH
+.loop
+ ld [hli], a
+ dec c
+ jr nz, .loop
+ ret
+
+Trade_CopyCableTilesOffScreen:
+; This is used to copy the link cable tiles off screen so that the cable
+; continues when the screen is scrolled.
+ push hl
+ hlcoord 0, 4
+ call CopyToRedrawRowOrColumnSrcTiles
+ pop hl
+ ld a, h
+ ldh [hRedrawRowOrColumnDest + 1], a
+ ld a, l
+ ldh [hRedrawRowOrColumnDest], a
+ ld a, REDRAW_ROW
+ ldh [hRedrawRowOrColumnMode], a
+ ld c, 10
+ jp DelayFrames
+
+Trade_AnimMonMoveHorizontal:
+; Animates the mon going through the link cable horizontally over a distance of
+; b 16-pixel units.
+ ld a, [wTradedMonMovingRight]
+ ld e, a
+ ld d, $8
+.scrollLoop
+ ld a, e
+ dec a
+ jr z, .movingRight
+; moving left
+ ldh a, [hSCX]
+ sub $2
+ jr .next
+.movingRight
+ ldh a, [hSCX]
+ add $2
+.next
+ ldh [hSCX], a
+ call DelayFrame
+ dec d
+ jr nz, .scrollLoop
+ call Trade_AnimCircledMon
+ dec b
+ jr nz, Trade_AnimMonMoveHorizontal
+ ret
+
+Trade_AnimCircledMon:
+; Cycles between the two animation frames of the mon party sprite, cycles
+; between a circle and an oval around the mon sprite, and makes the cable flash.
+ push de
+ push bc
+ push hl
+ ldh a, [rBGP]
+ xor $3c ; make link cable flash
+ ldh [rBGP], a
+ call UpdateGBCPal_BGP
+ ld hl, wOAMBuffer + $02
+ ld de, $4
+ ld c, $14
+.loop
+ ld a, [hl]
+ xor ICONOFFSET
+ ld [hl], a
+ add hl, de
+ dec c
+ jr nz, .loop
+ pop hl
+ pop bc
+ pop de
+ ret
+
+Trade_WriteCircledMonOAM:
+ farcall WriteMonPartySpriteOAMBySpecies
+ call Trade_WriteCircleOAM
+
+Trade_AddOffsetsToOAMCoords:
+ ld hl, wOAMBuffer
+ ld c, $14 ; SCREEN_WIDTH?
+.loop
+ ld a, [wBaseCoordY]
+ add [hl]
+ ld [hli], a
+ ld a, [wBaseCoordX]
+ add [hl]
+ ld [hli], a
+ inc hl
+ inc hl
+ dec c
+ jr nz, .loop
+ ret
+
+Trade_AnimMonMoveVertical:
+; Animates the mon going through the link cable vertically as well as
+; horizontally for a bit. The last bit of horizontal movement (when moving
+; right) or the first bit of horizontal movement (when moving left) are done
+; here instead of Trade_AnimMonMoveHorizontal because this function moves the
+; sprite itself rather than scrolling the screen around the sprite. Moving the
+; sprite itself is necessary because the vertical segment of the link cable is
+; to the right of the screen position that the mon sprite has when
+; Trade_AnimMonMoveHorizontal is executing.
+ ld a, [wTradedMonMovingRight]
+ and a
+ jr z, .movingLeft
+; moving right
+ lb bc, 4, 0 ; move right
+ call .doAnim
+ lb bc, 0, 10 ; move down
+ jr .doAnim
+.movingLeft
+ lb bc, 0, -10 ; move up
+ call .doAnim
+ lb bc, -4, 0 ; move left
+.doAnim
+ ld a, b
+ ld [wBaseCoordX], a
+ ld a, c
+ ld [wBaseCoordY], a
+ ld d, $4
+.loop
+ call Trade_AddOffsetsToOAMCoords
+ call Trade_AnimCircledMon
+ ld c, 8
+ call DelayFrames
+ dec d
+ jr nz, .loop
+ ret
+
+Trade_WriteCircleOAM:
+; Writes the OAM blocks for the circle around the traded mon as it passes
+; the link cable.
+ ld hl, Trade_CircleOAMPointers
+ ld c, $4
+ xor a
+.loop
+ push bc
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ inc hl
+ ld c, [hl]
+ inc hl
+ ld b, [hl]
+ inc hl
+ push hl
+ inc a
+ push af
+ call WriteOAMBlock
+ pop af
+ pop hl
+ pop bc
+ dec c
+ jr nz, .loop
+ ret
+
+trade_circle_oam: MACRO
+ dw \1
+ db \2, \3
+ENDM
+
+Trade_CircleOAMPointers:
+ ; oam pointer, upper-left x coord, upper-left y coord
+ trade_circle_oam Trade_CircleOAM0, $08, $08
+ trade_circle_oam Trade_CircleOAM1, $18, $08
+ trade_circle_oam Trade_CircleOAM2, $08, $18
+ trade_circle_oam Trade_CircleOAM3, $18, $18
+
+Trade_CircleOAM0:
+ dbsprite 2, 7, 0, 0, ICON_TRADEBUBBLE << 2 + 1, OAM_OBP1
+ dbsprite 2, 7, 0, 2, ICON_TRADEBUBBLE << 2 + 3, OAM_OBP1
+
+Trade_CircleOAM1:
+ dbsprite 6, 7, 0, 1, ICON_TRADEBUBBLE << 2 + 0, OAM_OBP1 | OAM_HFLIP
+ dbsprite 6, 7, 0, 3, ICON_TRADEBUBBLE << 2 + 2, OAM_OBP1 | OAM_HFLIP
+
+Trade_CircleOAM2:
+ dbsprite 10, 7, 0, 2, ICON_TRADEBUBBLE << 2 + 3, OAM_OBP1 | OAM_VFLIP
+ dbsprite 10, 7, 0, 0, ICON_TRADEBUBBLE << 2 + 1, OAM_OBP1 | OAM_VFLIP
+
+Trade_CircleOAM3:
+ dbsprite 14, 7, 0, 3, ICON_TRADEBUBBLE << 2 + 2, OAM_OBP1 | OAM_HFLIP | OAM_VFLIP
+ dbsprite 14, 7, 0, 1, ICON_TRADEBUBBLE << 2 + 0, OAM_OBP1 | OAM_HFLIP | OAM_VFLIP
+
+; a = species
+Trade_LoadMonSprite:
+ ld [wcf91], a
+ ld [wd0b5], a
+ ld [wWholeScreenPaletteMonSpecies], a
+ ld b, SET_PAL_POKEMON_WHOLE_SCREEN
+ ld c, 0
+ call RunPaletteCommand
+ ldh a, [hAutoBGTransferEnabled]
+ xor $1
+ ldh [hAutoBGTransferEnabled], a
+ call GetMonHeader
+ hlcoord 7, 2
+ call LoadFlippedFrontSpriteByMonIndex
+ ld c, 10
+ jp DelayFrames
+
+Trade_ShowClearedWindow:
+; clears the window and covers the BG entirely with the window
+ ld a, $1
+ ldh [hAutoBGTransferEnabled], a
+ call ClearScreen
+ ld a, %11100011
+ ldh [rLCDC], a
+ ld a, $7
+ ldh [rWX], a
+ xor a
+ ldh [hWY], a
+ ld a, $90
+ ldh [hSCX], a
+ ret
+
+Trade_SlideTextBoxOffScreen:
+; Slides the window right until it's off screen. The window usually just has
+; a text box at the bottom when this is called. However, when this is called
+; after Trade_ShowEnemyMon in the external clock sequence, there is a mon pic
+; above the text box and it is also scrolled off the screen.
+ ld c, 50
+ call DelayFrames
+.loop
+ call DelayFrame
+ ldh a, [rWX]
+ inc a
+ inc a
+ ldh [rWX], a
+ cp $a1
+ jr nz, .loop
+ call Trade_ClearTileMap
+ ld c, 10
+ call DelayFrames
+ ld a, $7
+ ldh [rWX], a
+ ret
+
+PrintTradeWentToText:
+ ld hl, TradeWentToText
+ call PrintText
+ ld c, 200
+ call DelayFrames
+ jp Trade_SlideTextBoxOffScreen
+
+TradeWentToText:
+ text_far _TradeWentToText
+ text_end
+
+PrintTradeForSendsText:
+ ld hl, TradeForText
+ call PrintText
+ call Trade_Delay80
+ ld hl, TradeSendsText
+ call PrintText
+ jp Trade_Delay80
+
+TradeForText:
+ text_far _TradeForText
+ text_end
+
+TradeSendsText:
+ text_far _TradeSendsText
+ text_end
+
+PrintTradeFarewellText:
+ ld hl, TradeWavesFarewellText
+ call PrintText
+ call Trade_Delay80
+ ld hl, TradeTransferredText
+ call PrintText
+ call Trade_Delay80
+ jp Trade_SlideTextBoxOffScreen
+
+TradeWavesFarewellText:
+ text_far _TradeWavesFarewellText
+ text_end
+
+TradeTransferredText:
+ text_far _TradeTransferredText
+ text_end
+
+PrintTradeTakeCareText:
+ ld hl, TradeTakeCareText
+ call PrintText
+ jp Trade_Delay80
+
+TradeTakeCareText:
+ text_far _TradeTakeCareText
+ text_end
+
+PrintTradeWillTradeText:
+ ld hl, TradeWillTradeText
+ call PrintText
+ call Trade_Delay80
+ ld hl, TradeforText
+ call PrintText
+ jp Trade_Delay80
+
+TradeWillTradeText:
+ text_far _TradeWillTradeText
+ text_end
+
+TradeforText:
+ text_far _TradeforText
+ text_end
+
+Trade_ShowAnimation:
+ ld [wAnimationID], a
+ xor a
+ ld [wAnimationType], a
+ predef_jump MoveAnimation
diff --git a/engine/movie/trade2.asm b/engine/movie/trade2.asm
new file mode 100755
index 00000000..f0d91846
--- /dev/null
+++ b/engine/movie/trade2.asm
@@ -0,0 +1,49 @@
+Trade_PrintPlayerMonInfoText:
+ hlcoord 5, 0
+ ld de, Trade_MonInfoText
+ call PlaceString
+ ld a, [wTradedPlayerMonSpecies]
+ ld [wd11e], a
+ predef IndexToPokedex
+ hlcoord 9, 0
+ ld de, wd11e
+ lb bc, LEADING_ZEROES | 1, 3
+ call PrintNumber
+ hlcoord 5, 2
+ ld de, wcf4b
+ call PlaceString
+ hlcoord 8, 4
+ ld de, wTradedPlayerMonOT
+ call PlaceString
+ hlcoord 8, 6
+ ld de, wTradedPlayerMonOTID
+ lb bc, LEADING_ZEROES | 2, 5
+ jp PrintNumber
+
+Trade_PrintEnemyMonInfoText:
+ hlcoord 5, 10
+ ld de, Trade_MonInfoText
+ call PlaceString
+ ld a, [wTradedEnemyMonSpecies]
+ ld [wd11e], a
+ predef IndexToPokedex
+ hlcoord 9, 10
+ ld de, wd11e
+ lb bc, LEADING_ZEROES | 1, 3
+ call PrintNumber
+ hlcoord 5, 12
+ ld de, wcd6d
+ call PlaceString
+ hlcoord 8, 14
+ ld de, wTradedEnemyMonOT
+ call PlaceString
+ hlcoord 8, 16
+ ld de, wTradedEnemyMonOTID
+ lb bc, LEADING_ZEROES | 2, 5
+ jp PrintNumber
+
+Trade_MonInfoText:
+ db "──№<DOT>"
+ next ""
+ next "OT/"
+ next "<ID>№<DOT>@"