diff options
author | Ryan Tandy <ryan@nardis.ca> | 2019-10-11 19:26:52 -0700 |
---|---|---|
committer | Ryan Tandy <ryan@nardis.ca> | 2019-10-11 19:26:52 -0700 |
commit | c01ed32c8b274f4d2312e70782071d68dea91f97 (patch) | |
tree | 7a54b4fee54c863701f7785432e7b2938b63aa66 | |
parent | 3855a686b67e1b32192438dce1ff4e214b47cec0 (diff) |
Disassemble Game Freak logo intro
-rw-r--r-- | engine/movie/gamefreak_presents.asm | 376 | ||||
-rw-r--r-- | gfx/intro/gamefreak_logo.png | bin | 0 -> 172 bytes | |||
-rw-r--r-- | gfx/intro/gamefreak_presents.png | bin | 0 -> 180 bytes | |||
-rw-r--r-- | gfx/intro/logo_sparkle.png | bin | 0 -> 111 bytes | |||
-rw-r--r-- | gfx/intro/logo_star.png | bin | 0 -> 109 bytes | |||
-rw-r--r-- | main.asm | 21 | ||||
-rw-r--r-- | wram.asm | 8 |
7 files changed, 396 insertions, 9 deletions
diff --git a/engine/movie/gamefreak_presents.asm b/engine/movie/gamefreak_presents.asm new file mode 100644 index 00000000..6b15472f --- /dev/null +++ b/engine/movie/gamefreak_presents.asm @@ -0,0 +1,376 @@ +Copyright_GFPresents: ; e49a8 (39:49a8) +; Play the copyright screen and GameFreak Presents sequence. +; Return carry if user cancels animation by pressing a button. + + call ClearBGPalettes + call ClearTileMap + + ld a, HIGH(vBGMap0) + ld [hBGMapAddress + 1], a + xor a ; LOW(vBGMap0) + ld [hBGMapAddress], a + + ld [hJoyDown], a + ld [hSCX], a + ld [hSCY], a + + ld a, SCREEN_HEIGHT_PX + ld [hWY], a + + call WaitBGMap + + ld b, SCGB_GAMEFREAK_LOGO + call GetSGBLayout + + call SetPalettes + + ld c, 10 + call DelayFrames + + callfar Copyright + + call WaitBGMap + + ld c, 100 + call DelayFrames + + call ClearTileMap + call GFPresents_Init + +.loop + call GFPresents_PlayFrame + jr nc, .loop + + ; high bits of wJumpTableIndex are recycled for some flags + ; this was set if user canceled by pressing a button + ld a, [wJumpTableIndex] + bit 6, a + jr nz, .canceled + + ; clear carry flag from GFPresents_PlayFrame + and a + ret + +.canceled + scf + ret + +GFPresents_Init: ; e49f3 (39:49f3) +; Load gfx and initialize variables + + ld de, GFPresentsGFX1 + ld hl, vTiles1 + lb bc, BANK(GFPresentsGFX1), 28 + call Get1bpp + + ld de, GFPresentsGFX2 + ld hl, vTiles1 tile 28 + lb bc, BANK(GFPresentsGFX2), 5 + call Request2bpp + + farcall ClearAnimatedObjectBuffer + + ld hl, wAnimatedObjectDynamicVTileOffsets + ld a, 6 + ld [hli], a + ld a, $8d + ld [hl], a + + xor a + ld [wJumpTableIndex], a + ld [$ce64], a + ld [wIntroSceneTimer], a + ld [hSCX], a + ld [hSCY], a + + ld a, 1 + ld [hBGMapMode], a + + ld a, SCREEN_HEIGHT_PX + ld [hWY], a + + lb de, %00100100, %11111000 + call DmgToCgbObjPals + ret + +GFPresents_PlayFrame: ; e4a37 (39:4a37) +; Play one frame of GFPresents sequence. +; Return carry when the sequence completes or is canceled. + + call JoyTextDelay + ld a, [hJoyLast] + and BUTTONS + jr nz, .pressed_button + + ; high bits of wJumpTableIndex are recycled for some flags + ; this is set when the sequence finished + ld a, [wJumpTableIndex] + bit 7, a + jr nz, .finish + + farcall AnimatedObjects_PlayFrame + + call GFPresents_HandleFrame + call DelayFrame + + ; ensure carry is cleared + and a + ret + +.pressed_button + ; high bits of wJumpTableIndex are recycled for some flags + ld hl, wJumpTableIndex + set 6, [hl] + +.finish + callfar ClearAnimatedObjectBuffer + call ClearTileMap + call ClearSprites + + ld c, 16 + call DelayFrames + + scf + ret + +GFPresents_HandleFrame: ; e4a6d (39:4a6d) +; Dispatch to the current scene handler + + ld a, [wJumpTableIndex] + ld e, a + ld d, 0 + ld hl, .scenes + add hl, de + add hl, de + ld a, [hli] + ld h, [hl] + ld l, a + jp hl + +.scenes + dw GFPresents_Star + dw GFPresents_PlaceLogo + dw GFPresents_LogoSparkles + dw GFPresents_PlacePresents + dw GFPresents_WaitForTimer + dw GFPresents_SetDoneFlag + +GFPresents_NextScene: ; e4a88 (39:4a88) + ld hl, wJumpTableIndex + inc [hl] + ret + +; unused? +Func_e4a8d: ; e4a8d (39:4a8d) + ld c, 64 + call DelayFrames + call GFPresents_NextScene + ret + +GFPresents_Star: ; e4a96 (39:4a96) + + ; tell GFPresents_PlaceLogo we haven't finished yet + xor a + ld [$ce64], a + + depixel 10, 11, 4, 0 + ld a, $16 + call InitAnimatedObjectStruct + + ; TODO set some flag in the struct? + ld hl, $c + add hl, bc + ld [hl], $80 + + ld de, SFX_GAME_FREAK_LOGO_GS + call PlaySFX + + call GFPresents_NextScene + ret + +GFPresents_PlaceLogo: ; e4ab2 (39:4ab2) +; Draw the Game Freak logo (may be initially invisible due to palette) + + ; wait until the star animation completed + ; TODO this is cleared above, but when is it set? + ld a, [$ce64] + and a + ret z + + depixel 10, 11, 4, 0 + ld a, $15 + call InitAnimatedObjectStruct + + call GFPresents_NextScene + + ; set timer for GFPresents_LogoSparkles + ld a, $80 + ld [wIntroSceneTimer], a + ret + +GFPresents_LogoSparkles: ; e4ac8 (39:4ac8) + + ld hl, wIntroSceneTimer + ld a, [hl] + and a + jr z, .done + dec [hl] + + ; add first text when timer passes half + cp $3f + call z, GFPresents_PlaceGameFreak + + ; add sparkles continuously + call GFPresents_Sparkle + ret + +.done + ; set (unused?) timer for GFPresents_PlacePresents + ld [hl], $80 + call GFPresents_NextScene + ret + +GFPresents_PlaceGameFreak: ; e4adf (39:4adf) + hlcoord 5, 12 + ld de, .game_freak + call PlaceString + ret + +.game_freak + db $80, $81, $82, $83, $8d, $84, $85, $83, $81, $86, "@" + +GFPresents_PlacePresents: ; e4af4 (39:4af4) + hlcoord 7, 13 + ld de, .presents + call PlaceString + + call GFPresents_NextScene + + ; set timer for GFPresents_WaitForTimer + ld a, $80 + ld [wIntroSceneTimer], a + ret + +.presents + db $87, $88, $89, $8a, $8b, $8c, "@" + +GFPresents_SetDoneFlag: ; e4b0d (39:4b0d) +; Tell GFPresents_PlayFrame and TitleScreenFrame (01:63da) that we're finished. + + ld hl, wJumpTableIndex + set 7, [hl] + ret + +GFPresents_WaitForTimer: ; e4b13 (39:4b13) +; Wait for the timer to elapse + + ld hl, wIntroSceneTimer + ld a, [hl] + and a + jr z, .done + dec [hl] + ret +.done + call GFPresents_NextScene + ret + +GFPresents_UpdateLogoPal: ; e4b20 (39:4b20) +; called from 29:5928 +; OBP1 was initialized at end of GFPresents_Init + + ; once we reached the final state, leave it alone + ld a, [rOBP1] + cp %10010000 + ret z + + ; wait 16 frames before next change + ld a, [wIntroSceneTimer] + and $f + ret nz + + ; rotate OBP1 by one color slot (2 bits) + ; DMG: logo is white, then light gray, then dark gray + ; CGB: logo is white, then yellow + ld a, [rOBP1] + rrca + rrca + call DmgToCgbObjPal1 + ret + +GFPresents_Sparkle: ; e4b33 (39:4b33) +; Initialize and configure a sparkle sprite. +; TODO unclear how this relates to the actual screen display, +; seems to be called more times than there are visible sparkles? + + ; 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 + depixel 11, 11 + ld a, $17 + call InitAnimatedObjectStruct + 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, .sparkle_vectors + add hl, de + add hl, de + + ; set the angle and distance for this sprite + ; bc+$b <- hl (angle), bc+$c <- 0, bc+$d <- hl+1 (distance) + ld e, l + ld d, h + ld hl, $b + add hl, bc + ld a, [de] + ld [hl], a + inc de + ld hl, $c + add hl, bc + ld [hl], 0 + inc hl + ld a, [de] + ld [hl], a + + ret + +.sparkle_vectors + ; values control final position of each sparkle + ; position is automatically animated along the vector + ; each entry emits two sparkles in opposite directions + ; angle (6 bits) and distance (tiles?) + 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 + +GFPresentsGFX1: +INCBIN "gfx/intro/gamefreak_presents.1bpp" +INCBIN "gfx/intro/gamefreak_logo.1bpp" + +GFPresentsGFX2: +INCBIN "gfx/intro/logo_star.2bpp" +INCBIN "gfx/intro/logo_sparkle.2bpp" diff --git a/gfx/intro/gamefreak_logo.png b/gfx/intro/gamefreak_logo.png Binary files differnew file mode 100644 index 00000000..7038efb5 --- /dev/null +++ b/gfx/intro/gamefreak_logo.png diff --git a/gfx/intro/gamefreak_presents.png b/gfx/intro/gamefreak_presents.png Binary files differnew file mode 100644 index 00000000..d5ff5c43 --- /dev/null +++ b/gfx/intro/gamefreak_presents.png diff --git a/gfx/intro/logo_sparkle.png b/gfx/intro/logo_sparkle.png Binary files differnew file mode 100644 index 00000000..feaa9c1f --- /dev/null +++ b/gfx/intro/logo_sparkle.png diff --git a/gfx/intro/logo_star.png b/gfx/intro/logo_star.png Binary files differnew file mode 100644 index 00000000..8fc2f734 --- /dev/null +++ b/gfx/intro/logo_star.png @@ -1426,29 +1426,36 @@ ChangeBox_: dr $e3d25, $e4000 SECTION "bank39", ROMX, BANK[$39] + CopyrightGFX: INCBIN "gfx/intro/copyright.2bpp" -TitleScreenGFX3: + IF DEF(GOLD) +TitleScreenGFX3: dr $e41e0, $e4260 TitleScreenGFX4: dr $e4260, $e4608 OptionsMenu: dr $e4608, $e49a8 -Copyright_GFPresents: - dr $e49a8, $e4cb1 -GoldSilverIntro: - dr $e4cb1, $e8000 ENDC IF DEF(SILVER) +TitleScreenGFX3: dr $e41e0, $e4220 TitleScreenGFX4: dr $e4220, $e4450 OptionsMenu: dr $e4450, $e47f0 -Copyright_GFPresents: - dr $e47f0, $e4af9 +ENDC + +INCLUDE "engine/movie/gamefreak_presents.asm" + +IF DEF(GOLD) +GoldSilverIntro: + dr $e4cb1, $e8000 +ENDC + +IF DEF(SILVER) GoldSilverIntro: dr $e4af9, $e8000 ENDC @@ -2106,9 +2106,13 @@ wMonType:: ds 1 ; ce5f wCurSpecies:: ds 1 ; ce60 wce61:: ds 1 ; ce61 wce62:: ds 1 ; ce62 -wce63:: ds 1 ; ce63 +wce63:: +wJumpTableIndex:: + db ; ce63 wce64:: ds 1 ; ce64 -wce65:: ds 1 ; ce65 +wce65:: +wIntroSceneTimer:: + db ; ce65 wce66:: ds 1 ; ce66 wRequested2bpp:: ds 1 ; ce67 |