diff options
Diffstat (limited to 'engine/movie')
| -rw-r--r-- | engine/movie/game_freak_intro.asm | 341 | ||||
| -rw-r--r-- | engine/movie/oak_speech.asm | 798 | ||||
| -rw-r--r-- | engine/movie/opening_cutscene.asm | 1230 | ||||
| -rw-r--r-- | engine/movie/title.asm | 636 |
4 files changed, 3005 insertions, 0 deletions
diff --git a/engine/movie/game_freak_intro.asm b/engine/movie/game_freak_intro.asm new file mode 100644 index 0000000..e8a7a00 --- /dev/null +++ b/engine/movie/game_freak_intro.asm @@ -0,0 +1,341 @@ +INCLUDE "constants.asm" + +SECTION "engine/movie/game_freak_intro.asm", ROMX + +GameFreakIntro:: +; Copyright screen and Game Freak logo + + call DisableLCD + call ClearVRAM + + ld a, HIGH(vBGMap0) + ldh [hBGMapAddress + 1], a + xor a + ldh [hBGMapAddress], a + ldh [hJoyState], a + ldh [hSCX], a + ldh [hSCY], a + + ld a, $90 + ldh [hWY], a + + call EnableLCD + + ld c, 10 + call DelayFrames + ld b, SGB_GS_TITLE_SCREEN + call GetSGBLayout + + callab IntroCopyRightInfo + + ld a, 1 + ldh [hBGMapMode], a + call WaitBGMap + call SetPalettes + + ld c, 3 * 60 ; 3 seconds + call DelayFrames + + xor a + ldh [hWY], a + call ClearTileMap + + call .Init +.loop + call .Frame + jr nc, .loop + +; this was set if user skipped the GF logo by pressing A + ld a, [wJumptableIndex] + bit 6, a + jr nz, .cancelled + +; clear carry flag from .PlayFrame + and a + ret + +.cancelled + scf + ret + +.Init: + call DisableLCD + + ld hl, vBGMap0 + ld bc, BG_MAP_WIDTH * SCREEN_HEIGHT + xor a + call ByteFill + + ld de, GameFreakLogoGFX + ld hl, vChars1 + lb bc, BANK(GameFreakLogoGFX), 28 + call Get1bpp + + ld hl, GameFreakLogoSparkleGFX + ld de, vChars1 tile $1C + ld bc, 5 tiles + ld a, BANK(GameFreakLogoSparkleGFX) + call FarCopyData + + callba InitEffectObject + + ld hl, wSpriteAnimDict + ld a, $27 ; SPRITE_ANIM_DICT_GS_SPLASH + ld [hli], a + ld a, $8d + ld [hl], a + + xor a + ld [wJumptableIndex], a + ld [wIntroSceneFrameCounter], a + ld [wIntroSceneTimer], a + ldh [hSCX], a + ldh [hSCY], a + + ld a, 1 + ldh [hBGMapMode], a + + ld a, SCREEN_HEIGHT_PX + ldh [hWY], a + call EnableLCD + + ld a, %11100100 + ld a, %11100100 ; redundant + ldh [rOBP0], a + ld a, %00100100 + ldh [rOBP1], a + ret + + +.Frame: +; Play one frame of GameFreakPresents sequence. +; Return carry when the sequence completes or is canceled. + ld hl, hJoypadDown + ld a, [hl] + and %00001111 + jr nz, .pressed + + ld a, [wJumptableIndex] + bit 7, a + jr nz, .Finished + + callba EffectObjectJumpNoDelay + + call GameFreakPresentsScene + call DelayFrame + and a + ret + +.pressed + ld hl, wJumptableIndex + set 6, [hl] + +.Finished: + callab InitEffectObject + call ClearTileMap + call ClearSprites + + ld c, 16 + call DelayFrames + + scf + ret + + +GameFreakPresentsScene: + jumptable .scenes, wJumptableIndex + +.scenes + dw GameFreakPresents_Wait64Frames + dw GameFreakPresents_Star + dw GameFreakPresents_PlaceLogo + dw GameFreakPresents_LogoSparkles + dw GameFreakPresents_PlacePresents + dw GameFreakPresents_WaitForTimer + dw GameFreakPresents_SetDoneFlag + +GameFreakPresents_NextScene: + ld hl, wJumptableIndex + inc [hl] + ret + +GameFreakPresents_Wait64Frames: + ld c, $40 + call DelayFrames + call GameFreakPresents_NextScene + ret + +GameFreakPresents_Star: + xor a + ld [wIntroSceneFrameCounter], a + ld de, $5458 + ld a, $3b ; SPRITE_ANIM_INDEX_GS_INTRO_STAR + call InitSpriteAnimStruct + + ld hl, $000c ; SPRITEANIMSTRUCT_VAR1 + add hl, bc + ld [hl], $a0 ; star path radius + + ld de, $0031 ; SFX_GAME_FREAK_LOGO (metronome?) + call PlaySFX + call GameFreakPresents_NextScene + ret + +GameFreakPresents_PlaceLogo: + ld a, [wIntroSceneFrameCounter] + and a + ret z + + ld de, $5458 + ld a, $3a ; SPRITE_ANIM_INDEX_GAMEFREAK_LOGO + call InitSpriteAnimStruct + call GameFreakPresents_NextScene + +; set timer for the next scene + ld a, 128 + ld [wIntroSceneTimer], a + ret + +GameFreakPresents_LogoSparkles: + ld hl, wIntroSceneTimer + ld a, [hl] + and a + jr z, .done + dec [hl] + +; add first text when timer passes half + cp 63 + call z, GameFreakPresents_PlaceGameFreak + +; add sparkles continuously + call GameFreakPresents_Sparkle + ret + +.done +; set timer for the next scene and go there + ld [hl], 128 + call GameFreakPresents_NextScene + ret + + +GameFreakPresents_PlaceGameFreak: + hlcoord 5, 12 + ld de, .game_freak + call PlaceString + ret + +.game_freak +; G A M E F R E A K + db $80, $81, $82, $83, $8d, $84, $85, $83, $81, $86 + db "@" + +GameFreakPresents_PlacePresents: + hlcoord 7, 13 + ld de, .presents + call PlaceString + call GameFreakPresents_NextScene + ld a, $80 + ld [wIntroSceneTimer], a + ret + +.presents +; P R E S E N T S + db $87, $88, $89, $8a, $8b, $8c + db "@" + +GameFreakPresents_SetDoneFlag: + ld hl, wJumptableIndex + set 7, [hl] + ret + +GameFreakPresents_WaitForTimer: + ld hl, wIntroSceneTimer + ld a, [hl] + and a + jr z, .done + dec [hl] + ret +.done + call GameFreakPresents_NextScene + ret + +GameFreakPresents_UpdateLogoPal: +; called from sprite animation routine + +; once we reached the final state, leave it alone + ldh a, [rOBP1] + cp %10010000 + ret z + +; wait 16 frames before next change + ld a, [wIntroSceneTimer] + and $0f + ret nz + +; rotate OBP1 by one color slot (2 bits) + ld hl, rOBP1 + rrc [hl] + rrc [hl] + ret + + +GameFreakPresents_Sparkle: +; Initialize and configure a sparkle sprite. + +; run only every second frame + ld d, a + and 1 + ret nz + +; shift over so our index is still changing by 1 each time + ld a, d + srl a +; set up a new sparkle sprite + push af + ld de, $5858 + ld a, $3c + call InitSpriteAnimStruct + pop af + +; take the bottom 4 bits of a as an index into +; sparkle_vectors (16 entries) + and %00001111 + ld e, a + ld d, 0 + ld hl, .vectors + add hl, de + add hl, de + +; set the angle and distance for this sprite + ld e, l + ld d, h + ld hl, $b ; SPRITEANIMSTRUCT_JUMPTABLE_INDEX + add hl, bc + ld a, [de] + ld [hl], a ; angle + inc de + ld hl, $c ; SPRITEANIMSTRUCT_VAR1 + add hl, bc + ld [hl], 0 + inc hl ; SPRITEANIMSTRUCT_VAR2 + ld a, [de] + ld [hl], a ; distance + ret + +.vectors + db $00, $03 + db $08, $04 + db $04, $03 + db $0c, $02 + db $10, $02 + db $18, $03 + db $14, $04 + db $1c, $03 + db $20, $02 + db $28, $02 + db $24, $03 + db $2c, $04 + db $30, $04 + db $38, $03 + db $34, $02 + db $3c, $04 diff --git a/engine/movie/oak_speech.asm b/engine/movie/oak_speech.asm new file mode 100644 index 0000000..5941f65 --- /dev/null +++ b/engine/movie/oak_speech.asm @@ -0,0 +1,798 @@ +INCLUDE "constants.asm" + +SECTION "engine/movie/oak_speech.asm", ROMX + +DemoStart:: + ld de, OakPic + lb bc, BANK(OakPic), $00 + call IntroDisplayPicCenteredOrUpperRight + call FadeInIntroPic + ld hl, OakSpeechDemo + call PrintText + call GBFadeOutToWhite + call ClearTileMap + ld de, ProtagonistPic + lb bc, BANK(ProtagonistPic), $00 + call IntroDisplayPicCenteredOrUpperRight + call MovePicLeft + ld a, %11010000 + ldh [rOBP0], a + call DemoSetUpPlayer + jp IntroCleanup + +GameStart:: + ld de, OakPic + lb bc, BANK(OakPic), $00 + call IntroDisplayPicCenteredOrUpperRight + call FadeInIntroPic + ld hl, OakSpeech1 + call PrintText + call GBFadeOutToWhite + call ClearTileMap + ld a, DEX_YADOKING + ld [wCurSpecies], a + ld [wMonDexIndex], a + call GetMonHeader + hlcoord 6, 4 + hlcoord 6, 4 + call PrepMonFrontpic + call MovePicLeft + ld hl, OakSpeech2 + call PrintText + ld a, DEX_YADOKING + call PlayCry + ld hl, OakSpeech3 + call PrintText + call GBFadeOutToWhite + call ClearTileMap + ld de, ProtagonistPic + lb bc, BANK(ProtagonistPic), $00 + call IntroDisplayPicCenteredOrUpperRight + call MovePicLeft + ld hl, OakSpeech4 + call PrintText + call ChoosePlayerName + call GBFadeOutToWhite + call ClearTileMap + ld de, RivalPic + lb bc, BANK(RivalPic), $00 + call IntroDisplayPicCenteredOrUpperRight + call FadeInIntroPic + ld hl, OakSpeech5 + call PrintText + call ChooseRivalName + call GBFadeOutToWhite + call ClearTileMap + ld de, OakPic + lb bc, BANK(OakPic), $00 + call IntroDisplayPicCenteredOrUpperRight + call FadeInIntroPic + ld hl, OakSpeech6 + call PrintText + callba SetClockDialog + call Function04ac + call GBFadeOutToWhite + call ClearTileMap + ld de, ProtagonistPic + lb bc, BANK(ProtagonistPic), $00 + call IntroDisplayPicCenteredOrUpperRight + call GBFadeInFromWhite + ld hl, OakSpeech7 + call PrintText + ldh a, [hROMBank] + push af + ld a, $20 + ld [wMusicFade], a + ld de, MUSIC_NONE + ld a, e + ld [wMusicFadeIDLow], a + ld a, d + ld [wMusicFadeIDHigh], a + ld de, $000B ; should be a constant - shrink noise? + call PlaySFX + pop af + call Bankswitch + ld c, $04 + call DelayFrames + +IntroCleanup:: + ld de, ShrinkPic1 + lb bc, BANK(ShrinkPic1), $00 + call IntroDisplayPicCenteredOrUpperRight + ld c, $04 + call DelayFrames + ld de, ShrinkPic2 + lb bc, BANK(ShrinkPic2), $00 + call IntroDisplayPicCenteredOrUpperRight + ld c, $14 + call DelayFrames + hlcoord 6, 5 + ld b, $07 + ld c, $07 + call ClearBox + ld c, $14 + call DelayFrames + call LoadStartingSprites + call LoadFontExtra + ld c, $32 + call DelayFrames + call GBFadeOutToWhite + call ClearTileMap + call Function0502 + ld a, $00 + ld [wd638], a + ld [wd637], a + +OverworldStart:: + call SetUpGameEntry + ld hl, wDebugFlags + bit CONTINUED_F, [hl] + call z, Function15b5 + ld hl, wd4a9 + set 0, [hl] + jp Function2a85 + +SetUpGameEntry:: + ld a, $04 + ld [wd65e], a + ld a, $F2 + ldh [hMapEntryMethod], a + ld hl, wDebugFlags + bit CONTINUED_F, [hl] ; if we loaded a game + ret nz + ld a, $F1 + ldh [hMapEntryMethod], a + ld a, $00 + ld [wDefaultSpawnPoint], a + ld hl, GameStartPlacement + ld de, wMapGroup + ld bc, wd65e - wMapGroup + call CopyBytes + ret + +GameStartPlacement:: + db $01 ; map group + db MAP_PLAYER_HOUSE_2F ; map + dwcoord 15, 45 ; screen anchor + db $04 ; metatile x + db $04 ; metatile y + db $00 ; in-metatile x + db $01 ; in-metatile y + +DebugSetUpPlayer:: + call SetPlayerNamesDebug + ld a, $0F + ld [wd15d], a + ld a, $42 + ld [wd15e], a + ld a, $3F + ld [wd15f], a + ld a, $FF + ld [wd163], a + ld [wd164], a + call GiveRandomJohto + ld a, $03 + call AddRandomPokemonToBox + call FillTMs + ld de, DebugBagItems + call FillBagWithList + ld hl, wPokedexOwned + call DebugFillPokedex + ld hl, wPokedexSeen + call DebugFillPokedex + ld hl, wAnnonDex + ld [hl], $01 + call Function40fd + ret + +DebugFillPokedex:: + ld b, $1F + ld a, $FF +.loop + ld [hl+], a + dec b + jr nz, .loop + ld [hl], $07 + ret + +FillBagWithList:: + ld hl, wNumBagItems +.loop + ld a, [de] + cp $FF + jr z, .yump + ld [wCurItem], a + inc de + ld a, [de] + inc de + ld [wItemQuantity], a + call ReceiveItem + jr .loop +.yump + ret + +DebugBagItems:: + db ITEM_IMPORTANT_BAG, $01 + db ITEM_BAG, $01 + db ITEM_TM_HOLDER, $01 + db ITEM_BALL_HOLDER, $01 + db ITEM_BICYCLE, $01 + db ITEM_MAIL, $06 + db ITEM_ULTRA_BALL, $1E + db ITEM_POKE_BALL, $63 + db ITEM_POTION, $1E + db ITEM_RARE_CANDY, $14 + db ITEM_MOON_STONE, $63 + db ITEM_FULL_HEAL, $63 + db ITEM_PROTEIN, $63 + db ITEM_QUICK_NEEDLE, $63 + db ITEM_SNAKESKIN, $63 + db ITEM_KINGS_ROCK, $63 + db ITEM_FLEE_FEATHER, $63 + db ITEM_FOCUS_ORB, $63 + db ITEM_SHARP_SCYTHE, $63 + db ITEM_DETECT_ORB, $63 + db $FF + +GiveRandomPokemon:: + and a + ret z +.loop + push af + call RandomUnder246 + ld b, $0A + call GivePokemon + pop af + dec a + jr nz, .loop + ret + +GiveRandomJohto:: +.loop + call Random + and $03 + jr z, .loop + dec a + ld b, a + add a, a + add a, b + add a, $98 ; maybe should be a constant - 152, aka the number of kanto pokes + ld b, $08 + call GivePokemon + ld a, $8D + ld [wPartyMon1 + 1], a + ret + +GiveKantoStarters:: + ld a, $03 + ld b, $20 + call GivePokemon + ld a, $06 + ld b, $24 + call GivePokemon + ld a, $09 + ld b, $24 + call GivePokemon + ret + +GivePokemon:: + ld [wMonDexIndex], a + ld a, b + ld [wCurPartyLevel], a + ld a, $10 + call Predef + ret + +AddRandomPokemonToBox: + and a + ret z +.loop + push af + xor a + ld [wca44], a + call RandomUnder246 + ld [wcdd7], a + ld a, $05 + ld [wCurPartyLevel], a + callab AddPokemonToBox + ld a, [wcdd7] + ld [wMonDexIndex], a + callab Functiondd5c + pop af + dec a + jr nz, .loop + ret + +RandomUnder246:: +.loop + call Random + and a + jr z, .loop + cp $F6 + jr nc, .loop + ret + +FillTMs:: + ld b, $39 + ld a, $01 + ld hl, wTMsHMs +.loop + ld [hl+], a + dec b + jr nz, .loop + ret + +DebugGiveKeyItems:: + ld hl, DebugKeyItemsList + ld de, wKeyItems + ld c, $FF +.loop + inc c + ld a, [hl+] + ld [de], a + inc de + cp $FF + jr nz, .loop + ld a, c + ld [wNumKeyItems], a + ret + +DebugKeyItemsList:: + db ITEM_TM_HOLDER + db ITEM_BALL_HOLDER + db ITEM_BAG + db ITEM_BICYCLE + db $FF + +DemoSetUpPlayer:: + ld hl, wPlayerName + ld de, DemoPlayerName + call CopyString + ld hl, wRivalName + ld de, DemoRivalName + call CopyString + call Function40fd + ld de, DemoItemList + call FillBagWithList + call GiveRandomJohto + ret + +DemoItemList:: + db ITEM_POKE_BALL, $05 + db ITEM_POTION, $0A + db ITEM_FULL_HEAL, $0A + db ITEM_STIMULUS_ORB, $01 + db ITEM_FOCUS_ORB, $01 + db $FF + +DemoPlayerName:: + db "サトシ@" + +DemoRivalName:: + db "シゲル@" + +OakSpeechDemo:: + text "ようこそ" + line "ポケット モンスターの せかいへ!" + cont "ごぞんじ わしが オーキドじゃ!" + + para "きょう きみに きてもらったのは" + line "ほかでもない" + cont "あたらしい ずかんづくりを" + cont "てつだって ほしいのじゃ!" + + para "もちろん" + line "きみの パートナーとなる ポケモンと" + cont "りュックは ようい しておる" + + para "りュックの なかには" + line "キズぐすりと" + cont "モンスターボールが" + cont "はいっておるから あんしんじゃ!" + + para "すでに きみの ライバルは" + line "しゅっぱつ しとる" + + para "まけないよう がんばって くれい!" + prompt + +OakSpeech1:: + text "いやあ またせた!" + + para "ポケット モンスターの せかいへ" + line "ようこそ!" + + para "わたしの なまえは オーキド" + + para "みんなからは # はかせと" + line "したわれて おるよ" + prompt + +OakSpeech2:: + text "きみも もちろん" + line "しっているとは おもうが" + + para "この せかいには" + line "ポケット モンスターと よばれる" + cont "いきもの たちが" + cont "いたるところに すんでいる!" + prompt + +OakSpeech3:: + text "その # という いきものを" + line "ひとは ぺットに したり" + cont "しょうぶに つかったり" + cont "そして・・・" + + para "わたしは この #の" + line "けんきゅうを してる というわけだ" + prompt + +OakSpeech4:: + text "では はじめに きみの なまえを" + line "おしえて もらおう!" + prompt + +OakSpeech5:: + text "そして この しょうねんは" + line "きみの おさななじみであり" + cont"ライバルである" + + para "・・・えーと?" + line "なまえは なんて いったかな?" + prompt + +OakSpeech6:: + text "さて きみの きねんすべき" + line "たびだちのひを" + cont "きろくしておこう!" + + para "じかんも なるべく せいかくにな!" + prompt + +OakSpeech7:: + text "<PLAYER>!" + + para "いよいよ これから" + line "きみの ものがたりの はじまりだ!" + + para "ゆめと ぼうけんと!" + line "ポケット モンスターの せかいへ!" + + para "レッツ ゴー!" + done + +SetPlayerNamesDebug:: + ld hl, DebugPlayerName + ld de, wPlayerName + call CopyNameDebug + ld hl, DebugRivalName + ld de, wRivalName + +CopyNameDebug: + ld bc, PLAYER_NAME_LENGTH + call CopyBytes + ret + +DebugPlayerName: + db "コージ@" + +DebugRivalName: + db "レッド@" + +ChoosePlayerName:: + call PanPortraitRight + ld hl, PlayerNameMenuHeader + call NamingWindow + ld a, [wMenuCursorY] + dec a + jr z, .loop + ld de, wPlayerName + call SaveCustomName + jr .farjump + +.loop + ld b, $01 + ld de, wPlayerName + callba NamingScreen + ld a, [wPlayerName] + cp "@" + jr z, .loop + + call GBFadeOutToWhite + call ClearTileMap + call LoadFontExtra + call WaitBGMap + ld de, $4D10 + ld bc, $1200 + call IntroDisplayPicCenteredOrUpperRight + call GBFadeInFromWhite +.farjump + ld hl, ChoosePlayerNameEndText + call PrintText + ret + +ChoosePlayerNameEndText: + text "ふむ・・・" + line "<PLAYER> と いうんだな!" + prompt + +PlayerNameMenuHeader: + db MENU_BACKUP_TILES ; flags + menu_coords 00, 00, 10, 11 + dw PlayerNameMenuData + db 01 ; initial selection + +PlayerNameMenuData: + db STATICMENU_CURSOR | STATICMENU_PLACE_TITLE | STATICMENU_DISABLE_B + db 04 ; items + db "じぶんできめる@" + db "ゴールド@" + db "サトシ@" + db "ジャック@" + db 3 ; x offset for the title string + db "なまえこうほ@" + +ChooseRivalName:: + call PanPortraitRight + ld hl, RivalNameMenuHeader + call NamingWindow + ld a, [wMenuCursorY] + dec a + jr z, .loop + ld de, wRivalName + call SaveCustomName + jr .farjump + +.loop + ld b, $02 + ld de, wRivalName + callba NamingScreen + ld a, [wRivalName] + cp "@" + jr z, .loop + + call GBFadeOutToWhite + call ClearTileMap + call LoadFontExtra + call WaitBGMap + ld de, $4BD4 + ld bc, $1200 + call IntroDisplayPicCenteredOrUpperRight + call GBFadeInFromWhite +.farjump + ld hl, ChooseRivalNameEndText + call PrintText + ret + +ChooseRivalNameEndText: + text "そうか そうだったな" + line "<RIVAL> という なまえだ" + prompt + +RivalNameMenuHeader: + db MENU_BACKUP_TILES ; flags + menu_coords 00, 00, 10, 11 + dw RivalNameMenuData + db 01 ; initial selection + +RivalNameMenuData: + db STATICMENU_CURSOR | STATICMENU_PLACE_TITLE | STATICMENU_DISABLE_B + db 04 ; items + db "じぶんできめる@" + db "シルバー@" + db "シゲル@" + db "ジョン@" + db 3 + db "なまえこうほ@" + +MomNamePrompt:: + ld hl, MomNameMenuHeader + call NamingWindow + ld a, [wMenuCursorY] + dec a + jr z, .loop + ld de, wMomsName + call SaveCustomName + jr .escape + +.loop + ld b, $03 + ld de, wMomsName + callba NamingScreen + ld a, [wMomsName] + cp "@" + jr z, .loop + + call ClearPalettes + call ClearTileMap + callab Function140d9 + call LoadFontExtra + call GetMemSGBLayout + call WaitBGMap +.escape + ret + +MomNameMenuHeader: + db MENU_BACKUP_TILES ; flags + menu_coords 00, 00, 10, 11 + dw .MomNameMenuData + db 01 ; initial selection + +.MomNameMenuData: + db STATICMENU_CURSOR | STATICMENU_PLACE_TITLE | STATICMENU_DISABLE_B + db 04 ; items + db "じぶんで きめる@" + db "おかあさん@" + db "ママ@" + db "かあちゃん@" + db 3 + db "なまえこうほ@" + +NamingWindow:: + ; loads the menu header put into hl + call LoadMenuHeader + call VerticalMenu + ld a, [wMenuCursorY] + dec a + call CopyNameFromMenu + call CloseWindow + ret + +SaveCustomName:: + ld hl, wStringBuffer2 + ld bc, PLAYER_NAME_LENGTH + call CopyBytes + ret + +PanPortraitRight:: + hlcoord 5, 4 + ld d, $06 + ld e, $7E + ld b, d + ld c, e + ld d, $00 + add hl, de +.loop + xor a + ldh [hBGMapMode], a + push hl + push bc +.innerLoop + ;pans all the tiles onscreen to the right one + ld a, [hl+] + ld [hl-], a + dec hl + dec c + jr nz, .innerLoop + + call WaitBGMap + pop bc + pop hl + inc hl + dec b ; passed c - how many tiles right to pan? + jr nz, .loop + ret + +PanPortraitLeft:: + hlcoord 12, 4 + ld b, $06 + ld c, $7E +.loop + xor a + ldh [hBGMapMode], a + push hl + push bc +.innerloop + ld a, [hl-] + ld [hl+], a + inc hl + dec c + jr nz, .innerloop + + call WaitBGMap + pop bc + pop hl + inc hl + dec b + jr nz, .loop + ret + +MenuCallSettings:: + call SettingsScreen + ret + +FadeInIntroPic: + ld hl, IntroFadePalettes + ld b, 6 +.next + ld a, [hl+] + ldh [rBGP], a + 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 [hWX], a + call DelayFrame + + ld a, %11100100 + ldh [rBGP], a +.next + call DelayFrame + ldh a, [hWX] + sub 8 + cp $FF + ret z + ldh [hWX], a + jr .next + +IntroDisplayPicCenteredOrUpperRight:: +; b = bank +; de = address of compressed pic +; c: 0 = centred, non-zero = upper-right + ld a, c + and a + hlcoord 13, 4 + jr nz, .skip + hlcoord 6, 4 +.skip + push hl + ld a, b + call UncompressSpriteFromDE + ld a, $00 + call OpenSRAM + ld hl, sSpriteBuffer1 + ld de, sSpriteBuffer0 + ld bc, DOUBLESPRITEBUFFERSIZE + call CopyBytes + call CloseSRAM + ld de, VRAM_Begin + $1000 + call InterlaceMergeSpriteBuffers + pop hl + xor a + ldh [hGraphicStartTile], a + ld bc, $0707 + predef PlaceGraphic + ret + +LoadStartingSprites: + ld de, GoldSpriteGFX + lb bc, BANK(GoldSpriteGFX), $0C + ld hl, VRAM_Begin + call Request2bpp + ld hl, wVirtualOAM + ld de, GameStartSprites + ld c, $04 +.loop + ld a, [de] + inc de + ld [hl+], a + ld a, [de] + inc de + ld [hl+], a + ld a, [de] + inc de + ld [hl+], a + xor a + ld [hl+], a + dec c + jr nz, .loop + ret + +GameStartSprites: + db $50, $48, $00 + db $50, $50, $01 + db $58, $48, $02 + db $58, $50, $03 diff --git a/engine/movie/opening_cutscene.asm b/engine/movie/opening_cutscene.asm new file mode 100644 index 0000000..1eeacb5 --- /dev/null +++ b/engine/movie/opening_cutscene.asm @@ -0,0 +1,1230 @@ +INCLUDE "constants.asm" + +SECTION "engine/movie/opening_cutscene.asm", ROMX + +OpeningCutscene:: + call .Init +.loop + call .PlayFrame + jr nc, .loop + ret + +.Init: + callba InitEffectObject + xor a + ld [wIntroJumptableIndex], a + ldh [hBGMapMode], a + ret + +.PlayFrame: + ld hl, hJoypadDown + ld a, [hl] + and %00001111 + jr nz, .Finish + +; check done flag + ld a, [wIntroJumptableIndex] + bit 7, a + jr nz, .Finish + + callba EffectObjectJumpNoDelay + call IntroSceneJumper + call DelayFrame + and a + ret + +.Finish: + callab InitEffectObject + call ClearSprites + call DelayFrame + xor a + ldh [hSCX], a + ldh [hSCY], a + ldh [hLCDCPointer], a + ldh [hLYOverrideStart], a + ldh [hLYOverrideEnd], a + ld a, %11100100 + ldh [rBGP], a + ldh [rOBP0], a + scf + ret + +IntroSceneJumper: + jumptable .scenes, wIntroJumptableIndex +.scenes + dw IntroScene1 + dw IntroScene2 + dw IntroScene3 + dw IntroScene4 + dw IntroScene5 + dw IntroScene6 + dw IntroScene7 + dw IntroScene8 + dw IntroScene9 + dw IntroScene10 + dw IntroScene11 + dw IntroScene12 + dw IntroScene13 + dw IntroScene14 + dw IntroScene15 + dw IntroScene16 + dw IntroScene17 + +IntroScene1: ; 43b8 +; Set up water cutscene + ld hl, wIntroJumptableIndex + inc [hl] + call DisableLCD + + ld b, SGB_GS_INTRO + ld c, 0 + call GetSGBLayout + + callab InitEffectObject + + call Intro_ResetLYOverrides + + ld hl, vChars2 + ld de, IntroUnderwaterGFX + call Intro_Copy128Tiles + +; Load water metatiles + ld a, LOW(Intro_WaterMeta) + ld [wIntroTilesPointer + 0], a + ld a, HIGH(Intro_WaterMeta) + ld [wIntroTilesPointer + 1], a + +; Set destination BG map pointer + ld hl, vBGMap0 + ld a, l + ld [wIntroBGMapPointer + 0], a + ld a, h + ld [wIntroBGMapPointer + 1], a + +; Load water tilemap + ld de, Intro_WaterTilemap + 15 tiles + ld a, e + ld [wIntroTilemapPointer + 0], a + ld a, d + ld [wIntroTilemapPointer + 1], a + call Intro_DrawBackground + +; draw GFX + ld hl, IntroWaterPokemonGFX + ld de, vChars0 + ld bc, $80 tiles +.draw_gfx + ld a, [hli] + ld [de], a + inc de + dec bc + ld a, b + or c + jr nz, .draw_gfx + + ld hl, wSpriteAnimDict + ld a, $21 + ld [hli], a + ld a, $00 + ld [hli], a + + xor a + ldh [hSCY], a + ld [wGlobalAnimYOffset], a + ld [wGlobalAnimXOffset], a + + ld a, $58 + ldh [hSCX], a + +; setup counter for the first scene + xor a + ld [wIntroFrameCounter2], a + ld a, $80 + ld [wIntroFrameCounter1], a + + ld a, LOW(rSCY) + ldh [hLCDCPointer], a + call Intro_InitSineLYOverrides + + xor a ; FALSE + ld [wIntroSpriteStateFlag], a + + call EnableLCD + call DelayFrame + + ld a, %11100100 + ldh [rBGP], a + ld a, %11100000 + ldh [rOBP0], a + call Intro_InitOmanyte + ret + +IntroScene2: ; 444a + call Intro_UpdateLYOverrides + ld hl, wIntroFrameCounter1 + ld a, [hl] + and a + jr z, .skip_intro + dec [hl] + call Intro_InitBubble + ret + +.skip_intro + ld [hl], $10 + ld hl, wIntroJumptableIndex + inc [hl] + +IntroScene3: +; rise towards the surface + call IntroScene3_Jumper + call IntroScene3_ScrollToSurface + ret nc +; next scene if carry flag is set + call Intro_ResetLYOverrides + ld hl, hSCY + inc [hl] + ld hl, wIntroJumptableIndex + inc [hl] + +IntroScene4: +; at surface; Lapras surfs to left of screen + ld a, [wIntroSpriteStateFlag] + and a + jr nz, .next + ld hl, wIntroFrameCounter2 + inc [hl] + ld a, [hl] + and $07 + jr nz, .skip_move_left + ld hl, hSCX + dec [hl] + +.skip_move_left + call Intro_AnimateOceanWaves + ret + +.next + ld hl, wIntroJumptableIndex + inc [hl] + xor a + ld [wIntroFrameCounter1], a + +IntroScene5: +; fade out + ld hl, wIntroFrameCounter1 + ld a, [hl] + inc [hl] + swap a + and $f + ld e, a + ld d, 0 + ld hl, .palettes + add hl, de + ld a, [hl] + cp -1 + jr z, .next + ldh [rBGP], a + call Intro_AnimateOceanWaves + ld hl, hSCX + dec [hl] + dec [hl] + ret +.next + ld hl, wIntroJumptableIndex + inc [hl] + ret + +.palettes: + db %11100100 + db %11100100 + db %10010000 + db %01000000 + db %00000000 + db -1 + +IntroScene17: +; delay a bit before leading into the title screen + ld c, 64 +.loop + call DelayFrame + dec c + jr nz, .loop +; set done flag + ld hl, wIntroJumptableIndex + set 7, [hl] + ret + +IntroScene3_ScrollToSurface: + ld hl, wIntroFrameCounter2 + inc [hl] + ld a, [hl] + and %00000011 + jr nz, .skip_move_left + ld hl, hSCX + dec [hl] + +.skip_move_left + and 1 + jr nz, .no_carry + ld hl, wGlobalAnimYOffset + inc [hl] + ld hl, hSCY + ld a, [hl] + dec [hl] + and $f + call z, Intro_UpdateTilemapAndBGMap + ld a, [wIntroFrameCounter1] + and a + jr z, .carry + +.no_carry + and a + ret + +.carry + scf + ret + +IntroScene3_Jumper: + jumptable .subroutines, wIntroFrameCounter1 +.subroutines + dw .scene3_2 + dw .scene3_2 + dw .scene3_2 + dw .scene3_1 + dw .scene3_2 + dw .scene3_2 + dw .scene3_3 + dw .scene3_3 + dw .scene3_3 + dw .scene3_4 + dw .scene3_5 + dw .scene3_6 + dw .scene3_6 + dw .scene3_6 + dw .scene3_6 + dw .scene3_6 + dw .scene3_6 + +.scene3_1: + call Intro_InitLapras + ld a, %11100100 + ldh [rOBP0], a + +.scene3_2: ; fallthrough + call Intro_AnimateOceanWaves + ret + +.scene3_3: + call Intro_InitMagikarps + call Intro_AnimateOceanWaves + ret + +.scene3_4: + ld hl, wIntroFrameCounter2 + ld a, [hl] + and %00011111 + jr z, .load_palettes + call Intro_InitMagikarps + ret +.load_palettes + callab Function962d ; load magikarp palettes + ret + +.scene3_5: + xor a + ldh [hLCDCPointer], a + ret + +.scene3_6: + call Intro_UpdateLYOverrides + ret + +Intro_InitBubble: + ld hl, wIntroFrameCounter1 + ld a, [hl] + and $0f + ret nz + + ld a, [hl] + and $70 + swap a + ld e, a + ld d, $00 + ld hl, .pixel_table + add hl, de + add hl, de + ld e, [hl] + inc hl + ld d, [hl] + ld a, $21 ; SPRITE_ANIM_INDEX_GS_INTRO_BUBBLE + call InitSpriteAnimStruct + ret + +.pixel_table + db $30, $74 + db $70, $94 + db $50, $84 + db $60, $78 + db $20, $68 + db $40, $88 + +Intro_InitMagikarps: + ld de, $403f + ld a, [wSGB] + and a + jr z, .ok + + ld de, $201f + +.ok + ld hl, wIntroFrameCounter2 + ld a, [hl] + and e + ret nz + ld a, [hl] + and d + jr nz, .alternate_frame + ld de, $e8e0 + call .PlaceMagikarp + ld de, wObject8SpriteXOffset + call .PlaceMagikarp + ld de, $00c0 + call .PlaceMagikarp + ret + +.alternate_frame + ld de, $e0f0 + call .PlaceMagikarp + ld de, $f8c0 + call .PlaceMagikarp + ld de, $10e0 + call .PlaceMagikarp + ret + +.PlaceMagikarp: + ld a, $23 ; SPRITE_ANIM_INDEX_GS_INTRO_MAGIKARP + call InitSpriteAnimStruct + ret + +Intro_InitOmanyte: + ld de, $9038 + call .PlaceOmanyte + ld de, $7050 + call .PlaceOmanyte + ld de, $8078 + +.PlaceOmanyte: + ld a, $22 ; SPRITE_ANIM_INDEX_GS_INTRO_SHELLDER + call InitSpriteAnimStruct + ret + +Intro_InitLapras: + ld a, [wIntroFrameCounter2] + and %00011111 + ret nz + ld de, $80c0 + ld a, $25 ; SPRITE_ANIM_INDEX_GS_INTRO_LAPRAS + call InitSpriteAnimStruct + ret + +Intro_UnusedInitAerodactyl: ; unreferenced + ld de, $1000 + ld a, $24 ; SPRITE_ANIM_INDEX_UNUSED_INTRO_AERODACTYL + call InitSpriteAnimStruct + ret + +Intro_UpdateTilemapAndBGMap: +; add new tiles to top as water scene scrolls up to surface + push hl + push de + + ld a, [wIntroTilemapPointer + 0] + ld e, a + ld a, [wIntroTilemapPointer + 1] + ld d, a + ld hl, -$10 + add hl, de + ld a, l + ld e, l + ld [wIntroTilemapPointer + 0], a + ld a, h + ld d, h + ld [wIntroTilemapPointer + 1], a + + hlcoord 0, 0 + ld c, BG_MAP_WIDTH / 2 +.loop + call Intro_Draw2x2Tiles + dec c + jr nz, .loop + + ld a, [wIntroBGMapPointer + 0] + ld e, a + ld a, [wIntroBGMapPointer + 1] + ld d, a + ld hl, hCurSpriteYCoord + add hl, de + ld a, l + ld [wIntroBGMapPointer + 0], a + ld [wVBCopyDst], a + ld a, h + and %11111011 + or %00001000 + ld [wIntroBGMapPointer + 1], a + ld [wVBCopyDst + 1], a + ld a, LOW(wTileMap) + ld [wVBCopySrc], a + ld a, HIGH(wTileMap) + ld [wVBCopySrc + 1], a + ld a, 4 + ld [wVBCopySize], a + ld hl, wIntroFrameCounter1 + dec [hl] + pop de + pop hl + ret + + +Intro_AnimateOceanWaves: +; uses a 2bpp request to copy tile IDs to the BG map + ld hl, wIntroFrameCounter2 + ld a, [hl] + and 3 + cp 3 + ret z + + ld a, [hl] + and $30 + swap a + ld l, a + ld h, 0 +rept 5 + add hl, hl +endr + ld de, .wave_tiles + add hl, de + ld a, l + ld [wVBCopySrc], a + ld a, h + ld [wVBCopySrc + 1], a + ld a, LOW(vBGMap0 + (15 * BG_MAP_WIDTH)) ; vBGMap0 row 15 + ld [wVBCopyDst], a + ld a, HIGH(vBGMap0 + (15 * BG_MAP_WIDTH)) ; vBGMap0 row 15 + ld [wVBCopyDst + 1], a + ld a, 2 + ld [wVBCopySize], a + ret +.wave_tiles: +; Fill an entire bg map row with each frame +rept 8 + db $70, $71, $72, $73 ; frame 1 +endr + +rept 8 + db $74, $75, $76, $77 ; frame 2 +endr + +rept 8 + db $78, $79, $7a, $7b ; frame 3 +endr + +rept 8 + db $7c, $7d, $7e, $7f ; frame 4 +endr + +Intro_InitSineLYOverrides: + ld bc, wLYOverrides2 + ld a, SCREEN_HEIGHT_PX + ld de, BG_MAP_WIDTH * BG_MAP_HEIGHT +.loop + push af + push de + callba BattleAnim_Sine_e + ld a, e + ld [bc], a + inc bc + pop de + inc e + pop af + dec a + jr nz, .loop + ret + +Intro_UpdateLYOverrides: + ld bc, wLYOverrides + ld e, $10 + +.loop1 + ldh a, [hSCY] + ld [bc], a + inc bc + dec e + jr nz, .loop1 + + ld hl, wLYOverrides2 + ld de, wLYOverrides2 + 1 + ld a, [hl] + push af + ld a, $80 + +.loop2 + push af + ld a, [de] + inc de + ld [hli], a + push hl + ld hl, hSCY + add [hl] + ld [bc], a + inc bc + pop hl + pop af + dec a + jr nz, .loop2 + + pop af + ld [hl], a + ret + +IntroScene6: +; Set up grass cutscene (Pikachu/Jigglypuff) + ld hl, wIntroJumptableIndex + inc [hl] + call DisableLCD + ld b, SGB_GS_INTRO + ld c, 1 + call GetSGBLayout + callab InitEffectObject + call Intro_ResetLYOverrides + ld hl, vChars2 + ld de, IntroForestGFX + call Intro_Copy128Tiles + ld a, LOW(Intro_GrassMeta) + ld [wIntroTilesPointer + 0], a + ld a, HIGH(Intro_GrassMeta) + ld [wIntroTilesPointer + 1], a + ld hl, vBGMap0 + ld a, l + ld [wIntroBGMapPointer + 0], a + ld a, h + ld [wIntroBGMapPointer + 1], a + ld de, Intro_GrassTilemap + 2 tiles + ld a, e + ld [wIntroTilemapPointer + 0], a + ld a, d + ld [wIntroTilemapPointer + 1], a + call Intro_DrawBackground + ld hl, IntroJigglypuffPikachuGFX + ld de, vChars0 + ld bc, $0a00 + +.load + ld a, [hli] + ld [de], a + inc de + dec bc + ld a, b + or c + jr nz, .load + + ld hl, wSpriteAnimDict + ld a, $22 + ld [hli], a + ld a, $00 + ld [hli], a + xor a + ldh [hSCY], a + ld [wGlobalAnimYOffset], a + ld a, $60 + ldh [hSCX], a + ld a, $a0 + ld [wGlobalAnimXOffset], a + xor a + ld [wIntroFrameCounter2], a + call EnableLCD + ld a, $e4 + ldh [rBGP], a + ldh [rOBP0], a + call Intro_InitJigglypuff + xor a + ld [wIntroSpriteStateFlag], a + ret + +IntroScene7: + call Intro_InitNote + ld hl, wIntroFrameCounter2 + ld a, [hl] + inc [hl] + and $03 + ret z + + ld hl, hSCX + ld a, [hl] + and a + jr z, .next + + dec [hl] + ld hl, wGlobalAnimXOffset + inc [hl] + ret + +.next + ld a, $ff + ld [wIntroFrameCounter1], a + call Intro_InitPikachu + ld hl, wIntroJumptableIndex + inc [hl] + ret + +IntroScene8: + ld hl, wIntroFrameCounter1 + ld a, [hl] + and a + jr z, .next + dec [hl] + call Intro_InitNote + ld hl, wIntroFrameCounter2 + inc [hl] + ret + +.next + xor a + ld [wIntroFrameCounter1], a + ld hl, wIntroJumptableIndex + inc [hl] + callab Function9633 + ret + +IntroScene9: + ld hl, wIntroFrameCounter1 + ld a, [hl] + inc [hl] + swap a + and $0f + ld e, a + ld d, $00 + ld hl, .palettes + add hl, de + ld a, [hl] + and a + jr z, .next + + ldh [rBGP], a + ld hl, hSCY + inc [hl] + ld hl, wGlobalAnimYOffset + dec [hl] + ret + +.next: + ld hl, wIntroJumptableIndex + inc [hl] + ret + +.palettes: +; fade out to black + db %11100100 + db %11100100 + db %11100100 + db %11100100 + db %11100100 + db %11111001 + db %11111110 + db %11111111 + db 0 + +Intro_DummyFunction: + ret + + +Intro_InitNote: + ld a, [wIntroSpriteStateFlag] + and a + ret nz + + ld hl, wIntroFrameCounter2 + ld a, [hl] + and $3f + ret nz + + ld a, [hl] + and $7f + jr z, .SmallerNote + + ld de, $5c30 + ld a, $26 ; SPRITE_ANIM_INDEX_GS_INTRO_NOTE + call InitSpriteAnimStruct + ret + +.SmallerNote: + ld de, $5430 + ld a, $27 ; SPRITE_ANIM_INDEX_GS_INTRO_SMALLER_NOTE + call InitSpriteAnimStruct + ret + + +Intro_InitJigglypuff: + ld de, $7030 + ld a, $28 ; SPRITE_ANIM_INDEX_GS_INTRO_JIGGLYPUFF + call InitSpriteAnimStruct + ret + + +Intro_InitPikachu: + ld de, $70c0 + ld a, $29 ; SPRITE_ANIM_INDEX_GS_INTRO_PIKACHU + call InitSpriteAnimStruct + ld de, $70c0 + ld a, $2a ; SPRITE_ANIM_INDEX_GS_INTRO_PIKACHU_TAIL + call InitSpriteAnimStruct + ret + +IntroScene10: +; Set up fireball cutscene (evolved Kanto starters) + ld hl, wIntroJumptableIndex + inc [hl] + ld b, SGB_GS_INTRO + ld c, 2 + call GetSGBLayout + callab InitEffectObject + call Intro_ResetLYOverrides + call Intro_BlankTilemapAndBGMap + + ld hl, vChars2 + ld de, IntroCharizard1GFX + lb bc, BANK(IntroCharizard1GFX), 8 tiles + call Request2bpp + + ld hl, vFont + ld de, IntroCharizard2GFX tile $40 + lb bc, BANK(IntroCharizard2GFX), 8 tiles + call Request2bpp + + ld hl, vChars0 + ld de, IntroCharizardFlamesGFX + lb bc, BANK(IntroCharizardFlamesGFX), 8 tiles + call Request2bpp + + ld hl, wSpriteAnimDict + ld a, $22 ; SPRITE_ANIM_DICT_GS_INTRO + ld [hli], a + ld a, $00 + ld [hli], a + + ld a, 0 + call DrawIntroCharizardGraphic + + ld a, $80 + ldh [hSCY], a + + xor a + ldh [hSCX], a + ld [wGlobalAnimYOffset], a + ld [wGlobalAnimXOffset], a + + xor a + ld [wIntroFrameCounter2], a + ld a, %00111111 + ldh [rBGP], a + ld a, %11111111 + ldh [rOBP0], a + ret + +IntroScene11: +; scroll up to Charizard silhoutte, flash Blastoise and Venusaur + ld hl, wIntroFrameCounter2 + ld a, [hl] + inc [hl] + and 1 + ret z + call Intro_CheckSCYEvent + ld hl, hSCY + ld a, [hl] + and a + jr z, .next + inc [hl] + ret + +.next + ld hl, wIntroJumptableIndex + inc [hl] + xor a + ld [wIntroFrameCounter1], a + +IntroScene12: +; load Charizard palettes + ld hl, wIntroFrameCounter1 + ld a, [hl] + inc [hl] + srl a + srl a + and 3 + ld e, a + ld d, 0 + ld hl, .palettes + add hl, de + ld a, [hl] + and a + jr z, .next + ldh [rBGP], a + ldh [rOBP0], a + ret + +.next + ld hl, wIntroJumptableIndex + inc [hl] + ld a, $80 + ld [wIntroFrameCounter1], a + ret + +.palettes: + db %01101010 + db %10100101 + db %11100100 + db %00000000 + +IntroScene13: +; Charizard mouth open + ld hl, wIntroFrameCounter1 + ld a, [hl] + and a + jr z, .next + + dec [hl] + ret + +.next + ld hl, wIntroJumptableIndex + inc [hl] + ld a, 1 + call DrawIntroCharizardGraphic + ld a, 4 + ld [wIntroFrameCounter1], a + ret + +IntroScene14: +; Charizard breathing fire + ld hl, wIntroFrameCounter1 + ld a, [hl] + and a + jr z, .next + dec [hl] + ret + +.next + ld hl, wIntroJumptableIndex + inc [hl] + ld a, 2 + call DrawIntroCharizardGraphic + ld a, 64 + ld [wIntroFrameCounter1], a + xor a + ld [wIntroFrameCounter2], a +; fallthrough + +IntroScene15: +; Charizard mouth wide open / fireball starts + call Intro_AnimateFireball + ld hl, wIntroFrameCounter1 + ld a, [hl] + and a + jr z, .next + dec [hl] + ret +.next + ld hl, wIntroJumptableIndex + inc [hl] + xor a + ld [wIntroFrameCounter1], a + ret + +IntroScene16: +; continue fireball / fade out palettes + call Intro_AnimateFireball + ld hl, wIntroFrameCounter1 + ld a, [hl] + inc [hl] + swap a + and $07 + ld e, a + ld d, $00 + ld hl, .palettes + add hl, de + ld a, [hl] + cp $ff + jr z, .next + ldh [rBGP], a + ldh [rOBP0], a + ret +.next + ld hl, wIntroJumptableIndex + inc [hl] + ret +.palettes: + db %11100100 + db %10010000 + db %01000000 + db %00000000 + db -1 + +Intro_BlankTilemapAndBGMap: + hlcoord 0, 0 + ld bc, SCREEN_WIDTH * SCREEN_HEIGHT +.blank_tilemap + ld [hl], 0 + inc hl + dec bc + ld a, b + or c + jr nz, .blank_tilemap + + ld hl, wOverworldMapBlocks ; $c600, buffer + ld bc, BG_MAP_WIDTH * BG_MAP_HEIGHT +.blank_bgmap + ld [hl], 0 + inc hl + dec bc + ld a, b + or c + jr nz, .blank_bgmap + + ld hl, vBGMap0 + ld de, wOverworldMapBlocks ; $c600, buffer + lb bc, BANK(@), $40 + call Request2bpp + ret + + +Intro_CheckSCYEvent: + ldh a, [hSCY] + ld c, a + ld hl, .Cuelist + +.loop + ld a, [hli] + cp -1 + ret z + cp c + jr z, .value_found + inc hl + inc hl + jr .loop + +.value_found + ld a, [hli] + ld h, [hl] + ld l, a + jp hl + +.Cuelist: + dbw $87, Intro_BlastoiseAppears + dbw $88, Intro_FlashMonPalette + dbw $98, Intro_FlashSilhouette + dbw $99, Intro_LoadVenusaurPalette + dbw $bf, Intro_VenusaurAppears + dbw $c0, Intro_FlashMonPalette + dbw $d0, Intro_FlashSilhouette + dbw $d1, Intro_LoadCharizardPalette + db -1 + +Intro_BlastoiseAppears: + call Intro_LoadBlastoiseObject + ret + +Intro_VenusaurAppears: + call Intro_LoadVenusaurObject + ret + +Intro_FlashMonPalette: + ld a, %11100100 + ldh [rOBP0], a + xor a + ldh [rBGP], a + ret + +Intro_FlashSilhouette: + ld a, %11111111 + ldh [rOBP0], a + ld a, %00111111 + ldh [rBGP], a + ret + +Intro_LoadVenusaurPalette: + callab Function9639 + ret + +Intro_LoadCharizardPalette: + callab Function963f + ret + + +DrawIntroCharizardGraphic: + push af + hlcoord 0, 6 + ld c, SCREEN_WIDTH * 8 + xor a +.loop1 + ld [hli], a + dec c + jr nz, .loop1 + + pop af + ld e, a + ld d, $00 + ld hl, .charizard_data +rept 5 + add hl, de +endr + ld e, [hl] + inc hl + ld c, [hl] + inc hl + ld b, [hl] + inc hl + ld a, [hli] + ld h, [hl] + ld l, a + ld a, e + +.loop2_outer + push bc + push hl +.loop2_inner + ld [hli], a + inc a + dec c + jr nz, .loop2_inner + + pop hl + ld bc, SCREEN_WIDTH + add hl, bc + pop bc + dec b + jr nz, .loop2_outer + + ld a, 1 + ldh [hBGMapMode], a + call DelayFrame + call DelayFrame + call DelayFrame + xor a + ldh [hBGMapMode], a + ret + +.charizard_data + db $00, $08, $08, $22, $c3 + db $40, $09, $08, $21, $c3 + db $88, $09, $08, $20, $c3 + +Intro_AnimateFireball: + ld hl, wIntroFrameCounter2 + ld a, [hl] + inc [hl] + and 3 + ret nz + ld de, $6454 + ld a, $2b ; SPRITE_ANIM_INDEX_GS_INTRO_FIREBALL + call InitSpriteAnimStruct + ld hl, hSCX + dec [hl] + ld hl, wGlobalAnimXOffset + inc [hl] + ret + +Intro_LoadBlastoiseObject: + ld de, $b008 + ld a, $2c ; SPRITE_ANIM_INDEX_GS_INTRO_BLASTOISE + call InitSpriteAnimStruct + ret + +Intro_LoadVenusaurObject: + ld de, $b0a0 + ld a, $2d ; SPRITE_ANIM_INDEX_GS_INTRO_VENUSAUR + call InitSpriteAnimStruct + ret + +Intro_Copy128Tiles: + ld bc, 128 tiles +.loop + ld a, [de] + inc de + ld [hli], a + dec bc + ld a, c + or b + jr nz, .loop + ret + + +Intro_DrawBackground: + ld b, BG_MAP_WIDTH / 2 +.outer_loop + push hl + ld c, BG_MAP_HEIGHT / 2 +.inner_loop + call Intro_Draw2x2Tiles + dec c + jr nz, .inner_loop + pop hl + push bc + ld bc, 2 * BG_MAP_WIDTH + add hl, bc + pop bc + dec b + jr nz, .outer_loop + ret + + +Intro_Draw2x2Tiles: + push bc + push de + push hl + push hl + push hl + ld a, [de] + ld l, a + ld h, 0 + ld a, [wIntroTilesPointer + 0] + ld e, a + ld a, [wIntroTilesPointer + 1] + ld d, a + add hl, hl + add hl, hl + add hl, de + ld e, l + ld d, h + pop hl + ld a, [de] + inc de + ld [hli], a + ld a, [de] + inc de + ld [hli], a + pop hl + ld bc, BG_MAP_WIDTH + add hl, bc + ld a, [de] + inc de + ld [hli], a + ld a, [de] + inc de + ld [hli], a + pop hl + inc hl + inc hl + pop de + inc de + pop bc + ret + + +Intro_ResetLYOverrides: + ld hl, wLYOverrides + xor a + ld c, wLYOverrides2 - wLYOverrides +.loop + ld [hli], a + dec c + jr nz, .loop + ret diff --git a/engine/movie/title.asm b/engine/movie/title.asm new file mode 100644 index 0000000..26d6f8b --- /dev/null +++ b/engine/movie/title.asm @@ -0,0 +1,636 @@ +INCLUDE "constants.asm" + +SECTION "engine/movie/title.asm@Title screen", ROMX + +IntroSequence:: + callab GameFreakIntro + jr c, TitleSequenceStart + ld a, [wTitleSequenceOpeningType] + and a + jr z, .opening_sequence + +.pikachu_minigame + callab PikachuMiniGame + jr TitleSequenceStart + +.opening_sequence + callab OpeningCutscene + +TitleSequenceStart:: + call TitleSequenceInit + callab SetTitleBGDecorationBorder + +.loop + call TitleScreenMain + jr nc, .loop + + call ClearBGPalettes + call ClearSprites + ld a, $01 + ldh [hBGMapMode], a + call ClearTileMap + call UpdateTimePals + + ld a, [wJumptableIndex + 1] + ld e, a + ld d, 0 + ld hl, TitleScreenJumpTable + add hl, de + add hl, de + ld a, [hli] + ld h, [hl] + ld l, a + + jp hl + +TitleScreenJumpTable:: + dw MainMenu + dw DebugMenu + dw SRAMClearMenu + dw IntroSequence + +TitleSequenceInit:: + call ClearPalettes + + xor a + ldh [hMapAnims], a + ldh [hSCY], a + ldh [hSCX], a + + ld de, MUSIC_NONE + call PlayMusic + + call ClearTileMap + call DisableLCD + call ClearSprites + + callba InitEffectObject + ld hl, vChars0 + ld bc, vBGMap0 - vChars0 + +.clear_loop + ld [hl], $00 + inc hl + dec bc + ld a, b + or c + jr nz, .clear_loop + + ld hl, TitleScreenGFX + ld de, vChars2 + 65 tiles + ld bc, 13 tiles + ld a, BANK(TitleScreenGFX) + call FarCopyData + + ld hl, TitleScreenVersionGFX + ld de, vChars2 + 96 tiles + ld bc, 24 tiles + ld a, BANK(TitleScreenVersionGFX) + call FarCopyData + + ld hl, TitleScreenHoOhGFX + ld de, vChars2 + ld bc, 49 tiles + ld a, BANK(TitleScreenHoOhGFX) + call FarCopyData + + ld hl, TitleScreenLogoGFX + ld de, vChars1 + ld bc, 58 tiles + ld a, BANK(TitleScreenLogoGFX) + call FarCopyData + + ld hl, TitleScreenGoldLogoGFX + ld de, vChars0 + 186 tiles + ld bc, 20 tiles + ld a, BANK(TitleScreenGoldLogoGFX) + call FarCopyData + + call SetTitleGfx + ld hl, wTileMapBackup + ld a, $24 + ld [hli], a + ld a, $00 + ld [hli], a + + ld hl, vBGMap0 + ld bc, 128 tiles + ld a, " " + call ByteFill + + ld b, $06 + call GetSGBLayout + call EnableLCD + ld a, $01 + ldh [hBGMapMode], a + call WaitBGMap + xor a + ldh [hBGMapMode], a + ld hl, wJumptableIndex + ld [hli], a ; (Possibly wJumptableIndex from Crystal) + ld [hli], a ; (Possibly wIntroSceneFrameCounter from Crystal) + ld [hli], a ; (Possibly wTitleScreenTimer from Crystal) + ld [hl], a ; (Possibly wTitleScreenTimer + 1 from Crystal) + + call .load_position_table + + + ld a, %00011010 + ldh [rBGP], a + ld a, %11100100 + ldh [rOBP0], a + ret + +.load_position_table: + ld hl, FirePositionTable + ld c, 6 ; Load 6 flying objects on the screen. + +.set_fire_note_loop + push bc + ld e, [hl] + inc hl + ld d, [hl] + inc hl + push hl + ld a, $2E ; Title fire/note object effect type? + call InitSpriteAnimStruct + pop hl + pop bc + dec c + jr nz, .set_fire_note_loop + ret + +FirePositionTable:: + dw $4CE0 + dw $58A0 + dw $6490 + dw $70D0 + dw $7CB0 + dw $8800 + +TitleFireGFX:: INCBIN "gfx/title/fire.2bpp" +TitleNotesGFX:: INCBIN "gfx/title/notes.2bpp" + +TitleScreenMain:: + ld a, [wJumptableIndex] + bit 7, a + jr nz, .exit + call TitleScreenSequence + callba EffectObjectJumpNoDelay + call DelayFrame + and a + ret + +.exit + scf + ret + +TitleScreenSequence:: + ld e, a + ld d, 0 + ld hl, TitleScreenSequenceTable + add hl, de + add hl, de + ld a, [hli] + ld h, [hl] + ld l, a + jp hl + +TitleScreenSequenceTable:: + dw TitleSeq_Start + dw TitleSeq_LoadPokemonLogo + dw TitleSeq_IncreaseJumpTableIndex + dw TitleSeq_IncreaseJumpTableIndex + dw TitleSeq_MoveTitle + dw TitleSeq_MoveTitleEnd + dw TitleSeq_InitFlashTitle + dw TitleSeq_FlashTitle + + dw TitleSeq_PMJapaneseChara + dw TitleSeq_IncreaseJumpTableIndex + dw TitleSeq_IncreaseJumpTableIndex + dw TitleSeq_IncreaseJumpTableIndex + dw TitleSeq_WaitForNextSequence + dw TitleSeq_PMSubtitle + dw TitleSeq_IncreaseJumpTableIndex + dw TitleSeq_IncreaseJumpTableIndex + + dw TitleSeq_IncreaseJumpTableIndex + dw TitleSeq_WaitForNextSequence + dw TitleSeq_Version + dw TitleSeq_IncreaseJumpTableIndex + dw TitleSeq_IncreaseJumpTableIndex + dw TitleSeq_IncreaseJumpTableIndex + dw TitleSeq_WaitForNextSequence + dw TitleSeq_CopyRight + + dw TitleSeq_IncreaseJumpTableIndex + dw TitleSeq_IncreaseJumpTableIndex + dw TitleSeq_IncreaseJumpTableIndex + dw TitleSeq_WaitForNextSequence + dw TitleSeq_HoOh + dw TitleSeq_IncreaseJumpTableIndex + dw TitleSeq_IncreaseJumpTableIndex + dw TitleSeq_IncreaseJumpTableIndex + + dw TitleSeq_WaitForNextSequence + dw TitleSeq_PressButtonInit + dw TitleSeq_TitleScreenInputAndTimeout + dw TitleSeq_FadeMusicOut + +TitleSeq_IncreaseJumpTableIndex:: + ld hl, wJumptableIndex + inc [hl] + ret + +TitleSeq_WaitForNextSequence:: + xor a + ldh [hBGMapMode], a + ld hl, wJumptableIndex + 2 + ld a, [hl] + and a + jr z, .next_seq + dec [hl] + ret + +.next_seq + call TitleSeq_IncreaseJumpTableIndex + ret + +TitleSeq_LoadPokemonLogo:: + call PrintPokemonLogo + call TitleSeq_IncreaseJumpTableIndex + ld a, $01 + ldh [hBGMapMode], a + ret + +TitleSeq_Start:: + call TitleSeq_IncreaseJumpTableIndex + push de + ld de, $2D ; "swish" sound + call PlaySFX + pop de + ld a, $80 + ld [wJumptableIndex + 2], a + call SetLYOverrides + ld a, $43 + ldh [hLCDCPointer], a + ret + +TitleSeq_MoveTitle:: + xor a + ldh [hBGMapMode], a + ld hl, wJumptableIndex + 2 + ld a, [hl] + and a + jr z, .nextseq + add $04 + ld [hl], a + ld e, a +.wait + ldh a, [rLY] + cp $40 + jr c, .wait + ld a, e + call SetLYOverrides + ret + +.nextseq + call TitleSeq_IncreaseJumpTableIndex + ret + +TitleSeq_MoveTitleEnd:: + xor a + ldh [hLCDCPointer], a + call TitleSeq_IncreaseJumpTableIndex + ld de, MUSIC_TITLE + call PlayMusic + ret + +TitleSeq_InitFlashTitle:: + call TitleSeq_IncreaseJumpTableIndex + ld a, %00011010 + ld [wJumptableIndex + 2], a + ld a, 6 + ld [wJumptableIndex + 3], a + ret + +TitleSeq_FlashTitle:: + ld hl, wJumptableIndex + 3 + ld a, [hl] + and a + jr z, .exit + dec [hl] + ld a, [wJumptableIndex + 2] + xor %00011010 + ld [wJumptableIndex +2 ], a + ldh [rBGP], a + call DelayFrame + call DelayFrame + ret + +.exit + call TitleSeq_IncreaseJumpTableIndex + ld a, %11100100 + ldh [rBGP], a + ret + +TitleSeq_PMJapaneseChara:: + call PrintPMJapaneseChara + ld a, $10 + ld [wJumptableIndex + 2], a + call TitleSeq_IncreaseJumpTableIndex + ld a, $01 + ldh [hBGMapMode], a + ret + +TitleSeq_PMSubtitle:: + call PrintPMSubtitle + ld a, $10 + ld [wJumptableIndex + 2], a + call TitleSeq_IncreaseJumpTableIndex + ld a, $01 + ldh [hBGMapMode], a + ret + +TitleSeq_Version:: + call PrintVersion + ld a, $10 + ld [wJumptableIndex + 2], a + call TitleSeq_IncreaseJumpTableIndex + ld a, $01 + ldh [hBGMapMode], a + ret + +TitleSeq_CopyRight:: + call PrintCopyRight + ld a, $10 + ld [wJumptableIndex + 2], a + call TitleSeq_IncreaseJumpTableIndex + ld a, $01 + ldh [hBGMapMode], a + ret + +TitleSeq_HoOh:: + call Set_HoOh + ld a, $10 + ld [wJumptableIndex + 2], a + call TitleSeq_IncreaseJumpTableIndex + ld a, $01 + ldh [hBGMapMode], a + ret + +TitleSeq_PressButtonInit:: + ld hl, wJumptableIndex + inc [hl] + ld hl, wJumptableIndex + 2 + ld de, DecodeNybble0Table - 3 + ld [hl], e + inc hl + ld [hl], d + ret + +TitleSeq_TitleScreenInputAndTimeout:: + ld hl, wJumptableIndex + 2 + ld e, [hl] + inc hl + ld d, [hl] + ld a, e + or d + jr z, .psbtn_reset + dec de + ld [hl], d + dec hl + ld [hl], e + call GetJoypad + ld hl, hJoyState +; UP + B + SELECT opens the SRAM clear screen + ld a, [hl] + and D_UP | B_BUTTON | SELECT + cp D_UP | B_BUTTON | SELECT + jr z, .psbtn_sramclear +; SELECT opens the debug menu + ld a, [hl] + and SELECT + jr nz, .psbtn_gotodebug + ld a, [hl] + and $09 + ret z + +.psbtn_play + ld a, $00 ; MainMenu + jr .psbtn_nextseq + +.psbtn_gotodebug + ld a, $01 ; DebugMenu + jr .psbtn_nextseq + +.psbtn_sramclear + ld a, $02 + +.psbtn_nextseq + ld [wJumptableIndex + 1], a + ld hl, wJumptableIndex + set 7, [hl] + ret + +.psbtn_reset + ld hl, wJumptableIndex + inc [hl] + xor a + ld [wMusicFadeID], a + ld [wMusicFadeID + 1], a + ld hl, wMusicFade + ld [hl], 8 + ret + +TitleSeq_FadeMusicOut:: + ld a, [wMusicFade] + and a + ret nz + ld a, 3 + ld [wJumptableIndex + 1], a + ld hl, wJumptableIndex + set 7, [hl] + ret + +SetLYOverrides:: + ld hl, wLYOverrides + ld c, $30 +.setly_loop + ld [hli], a + dec c + jr nz, .setly_loop + ret + +PrintPMSubtitle:: + coord hl, 2, 6 + ld b, 15 + ld a, $69 + jr LoadPrintArea + +PrintVersion:: + coord hl, 4, 1 + ld b, $09 + ld a, $60 + +LoadPrintArea:: + ld [hli], a + inc a + dec b + jr nz, LoadPrintArea + ret + +PrintPMJapaneseChara:: + coord hl, 15, 2 + ld a, "こ" + lb bc, 4, 4 + jr PrintBoxArea + +PrintPokemonLogo:: + coord hl, 15, 3 + ld [hl], $B8 + coord hl, 15, 4 + ld [hl], $B9 + coord hl, 1, 2 + ld a, $80 + ld bc, $0E04 + +PrintBoxArea:: + ld de, SCREEN_WIDTH + push bc + push hl + +.xloop + ld [hli], a + inc a + dec b + jr nz, .xloop + pop hl + add hl, de + pop bc + dec c + jr nz, PrintBoxArea + ret + +PrintCopyRight:: + coord hl, 3, 17 + ld a, $41 + ld b, $0D + +.loop + ld [hli], a + inc a + dec b + jr nz, .loop + ret + +SRAMClearMenu:: + call ClearTileMap + call GetMemSGBLayout + call LoadFont + call LoadFontExtra + ld hl, SRAMClear_Message + call PrintText + ld hl, SRAMClear_WinPOS + call CopyMenuHeader + call VerticalMenu + jp c, Init + ld a, [wMenuCursorY] + cp $01 + jp z, Init + + callab InitAllSRAMBanks + jp Init + +SRAMClear_Message:: + db "<NULL>すべての セーブデータエりアを" + db "<LINE>クりア しますか?<DONE>" + +SRAMClear_WinPOS:: + db 0 + db 7,14,11,19 + dw SRAMClear_TextChoice ; menu data + db 1 ; default option + +SRAMClear_TextChoice:: + db %11000000 + db 2 + db "いいえ@" + db "はい@" + +IntroCopyRightInfo:: + call ClearTileMap + call LoadFontExtra + ld de, TitleScreenGFX + ld hl, $9600 + lb bc, BANK(TitleScreenGFX), $19 + call Request2bpp + + coord hl, 5, 7 + ld de, IntroCopyRightInfo_Text + jp PlaceString + +IntroCopyRightInfo_Text:: + db $60, $61, $62, $63, $6D, $6E, $6F, $70, $71, $72, $4E ; "ⓒ1997 Nintendo\n" + db $60, $61, $62, $63, $73, $74, $75, $76, $77, $78, $6B, $6C, $4E ; "ⓒ1997 Creatures Inc.\n" + db $60, $61, $62, $63, $64, $65, $66, $67, $68, $69, $6A, $6B, $6C, $50 ; "ⓒ1997 GAME FREAK Inc.\0" + +Set_HoOh:: + coord hl, 7, 9 + ld de, $000D + ld a, $00 + ld b, $07 +.loop + ld c, $07 +.loop2 + ld [hli], a + inc a + dec c + jr nz, .loop2 + add hl, de + dec b + jr nz, .loop + ret + +; Unused code, looks like it sets the font type for the logo? +SetTitleFont:: + ld de, vChars1 + ld hl, TitleScreenLogoGFX + ld bc, 130 tiles + ld a, $04 + jp FarCopyDataDouble + +; Sets the type of art that will be displayed on the title screen +; depending on wTitleSequenceOpeningType. +SetTitleGfx:: + ld hl, wTitleSequenceOpeningType + ld a, [hl] + xor $01 + ld [hl], a + jr nz, .flame + +.note + ld hl, TitleNotesGFX + jr SetTitleGfxNext + +.flame + ld hl, TitleFireGFX +SetTitleGfxNext:: + ld de, vChars0 + ld c, $80 +.loop + ld a, [hli] + ld [de], a + inc de + dec c + jr nz, .loop + ret + +SECTION "engine/movie/title.asm@Title screen TEMPORARY", ROMX + +GameInit:: + call ClearWindowData + ld a, $23 + ld [wce5f], a + jp IntroSequence |
