First Commit

Upload literally everything from the pokecrystal16 expand-move-ID branch
This commit is contained in:
Zeta_Null 2023-09-10 12:35:35 -04:00
commit 2f8a41f833
4618 changed files with 480386 additions and 0 deletions

612
engine/movie/credits.asm Normal file
View file

@ -0,0 +1,612 @@
SECTION "Credits", ROMX
Credits::
bit 6, b ; Hall Of Fame
ld a, $0
jr z, .okay
ld a, $40
.okay
ld [wJumptableIndex], a
ldh a, [rSVBK]
push af
ld a, BANK(wGBCPalettes)
ldh [rSVBK], a
call ClearBGPalettes
call ClearTilemap
call ClearSprites
ld hl, wCreditsBlankFrame2bpp
ld c, (wCreditsBlankFrame2bppEnd - wCreditsBlankFrame2bpp) / 2
ld de, `22222222 ; eight pixels, each color #2 (dark)
; Fill wCreditsBlankFrame2bpp with 4x4=16 tiles, all solid dark color
; (the same color used for the four border frame mons' backgrounds)
.load_loop
ld a, e
ld [hli], a
ld a, d
ld [hli], a
dec c
jr nz, .load_loop
ld de, CreditsBorderGFX
ld hl, vTiles2 tile $20
lb bc, BANK(CreditsBorderGFX), 9
call Request2bpp
ld de, CopyrightGFX
ld hl, vTiles2 tile $60
lb bc, BANK(CopyrightGFX), 29
call Request2bpp
ld de, TheEndGFX
ld hl, vTiles2 tile $40
lb bc, BANK(TheEndGFX), 16
call Request2bpp
ld a, $ff
ld [wCreditsBorderFrame], a
xor a
ld [wCreditsBorderMon], a
call Credits_LoadBorderGFX
ld e, l
ld d, h
ld hl, vTiles2
lb bc, BANK(CreditsMonsGFX), 16
call Request2bpp
call ConstructCreditsTilemap
xor a
ld [wCreditsLYOverride], a
ld hl, wLYOverrides
ld bc, $100
xor a
call ByteFill
ld a, LOW(rSCX)
ldh [hLCDCPointer], a
call GetCreditsPalette
call SetPalettes
; BUG: Credits sequence changes move selection menu behavior (see docs/bugs_and_glitches.md)
ldh a, [hVBlank]
push af
ld a, $5
ldh [hVBlank], a
ld a, TRUE
ldh [hInMenu], a
xor a
ldh [hBGMapMode], a
ld [wCreditsPos], a
ld [wCreditsPos + 1], a
ld [wCreditsTimer], a
.execution_loop
call Credits_HandleBButton
call Credits_HandleAButton
jr nz, .exit_credits
call Credits_Jumptable
call DelayFrame
jr .execution_loop
.exit_credits
call ClearBGPalettes
xor a
ldh [hLCDCPointer], a
ldh [hBGMapAddress], a
pop af
ldh [hVBlank], a
pop af
ldh [rSVBK], a
ret
Credits_HandleAButton:
ldh a, [hJoypadDown]
and A_BUTTON
ret z
ld a, [wJumptableIndex]
bit 7, a
ret
Credits_HandleBButton:
ldh a, [hJoypadDown]
and B_BUTTON
ret z
ld a, [wJumptableIndex]
bit 6, a
ret z
ld hl, wCreditsPos
ld a, [hli]
cp $d
jr nc, .okay
ld a, [hli]
and a
ret z
.okay
ld hl, wCreditsTimer
ld a, [hl]
and a
ret z
dec [hl]
ret
Credits_Jumptable:
ld a, [wJumptableIndex]
and $f
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 ParseCredits
dw Credits_Next
dw Credits_Next
dw Credits_PrepBGMapUpdate
dw Credits_UpdateGFXRequestPath
dw Credits_RequestGFX
dw Credits_LYOverride
dw Credits_Next
dw Credits_Next
dw Credits_Next
dw Credits_UpdateGFXRequestPath
dw Credits_RequestGFX
dw Credits_LoopBack
Credits_Next:
ld hl, wJumptableIndex
inc [hl]
ret
Credits_LoopBack:
ld hl, wJumptableIndex
ld a, [hl]
and $f0
ld [hl], a
ret
Credits_PrepBGMapUpdate:
xor a
ldh [hBGMapMode], a
jp Credits_Next
Credits_UpdateGFXRequestPath:
call Credits_LoadBorderGFX
ld a, l
ld [wRequested2bppSource], a
ld a, h
ld [wRequested2bppSource + 1], a
ld a, LOW(vTiles2)
ld [wRequested2bppDest], a
ld a, HIGH(vTiles2)
ld [wRequested2bppDest + 1], a
jr Credits_RequestGFX
Credits_RequestGFX:
xor a
ldh [hBGMapMode], a
ld a, 8
ld [wRequested2bppSize], a
jp Credits_Next
Credits_LYOverride:
ldh a, [rLY]
cp $30
jr c, Credits_LYOverride
ld a, [wCreditsLYOverride]
dec a
dec a
ld [wCreditsLYOverride], a
ld hl, wLYOverrides + $1f
call .Fill
ld hl, wLYOverrides + $87
call .Fill
jp Credits_Next
.Fill:
ld c, $8
.loop
ld [hli], a
dec c
jr nz, .loop
ret
ParseCredits:
ld hl, wJumptableIndex
bit 7, [hl]
jp nz, .done
; Wait until the timer has run out to parse the next command.
ld hl, wCreditsTimer
ld a, [hl]
and a
jr z, .parse
; One tick has passed.
dec [hl]
jp .done
.parse
; First, let's clear the current text display,
; starting from line 5.
xor a
ldh [hBGMapMode], a
hlcoord 0, 5
ld bc, SCREEN_WIDTH * 12
ld a, " "
call ByteFill
; Then read the script.
.loop
call .get
; Commands:
cp CREDITS_END
jp z, .end
cp CREDITS_WAIT
jr z, .wait
cp CREDITS_SCENE
jr z, .scene
cp CREDITS_CLEAR
jr z, .clear
cp CREDITS_MUSIC
jr z, .music
cp CREDITS_WAIT2
jr z, .wait2
cp CREDITS_THEEND
jr z, .theend
; If it's not a command, it's a string identifier.
push af
ld e, a
ld d, 0
ld hl, CreditsStringsPointers
add hl, de
add hl, de
ld a, [hli]
ld d, [hl]
ld e, a
pop af
; Strings spanning multiple lines have special cases.
cp COPYRIGHT
jr z, .copyright
cp STAFF
jr c, .staff
; The rest start from line 6.
hlcoord 0, 6
jr .print
.copyright
hlcoord 2, 6
jr .print
.staff
hlcoord 0, 6
.print
; Print strings spaced every two lines.
call .get
ld bc, SCREEN_WIDTH * 2
call AddNTimes
call PlaceString
jr .loop
.theend
; Display "The End" graphic.
call Credits_TheEnd
jr .loop
.scene
; Update the scene number and corresponding palette.
call .get
ld [wCreditsBorderMon], a ; scene
xor a
ld [wCreditsBorderFrame], a ; frame
call GetCreditsPalette
call SetPalettes ; update hw pal registers
jr .loop
.clear
; Clear the banner.
ld a, $ff
ld [wCreditsBorderFrame], a ; frame
jr .loop
.music
; Play the credits music.
ld de, MUSIC_CREDITS
push de
ld de, MUSIC_NONE
call PlayMusic
call DelayFrame
pop de
call PlayMusic
jp .loop
.wait2
; Wait for some amount of ticks.
call .get
ld [wCreditsTimer], a
jr .done
.wait
; Wait for some amount of ticks, and do something else.
call .get
ld [wCreditsTimer], a
xor a
ldh [hBGMapThird], a
ld a, 1
ldh [hBGMapMode], a
.done
jp Credits_Next
.end
; Stop execution.
ld hl, wJumptableIndex
set 7, [hl]
ld a, 32
ld [wMusicFade], a
ld a, LOW(MUSIC_POST_CREDITS)
ld [wMusicFadeID], a
ld a, HIGH(MUSIC_POST_CREDITS)
ld [wMusicFadeID + 1], a
ret
.get
; Get byte wCreditsPos from CreditsScript
push hl
push de
ld a, [wCreditsPos]
ld e, a
ld a, [wCreditsPos + 1]
ld d, a
ld hl, CreditsScript
add hl, de
inc de
ld a, e
ld [wCreditsPos], a
ld a, d
ld [wCreditsPos + 1], a
ld a, [hl]
pop de
pop hl
ret
ConstructCreditsTilemap:
xor a
ldh [hBGMapMode], a
ld a, $c
ldh [hBGMapAddress], a
ld a, $28
hlcoord 0, 0
ld bc, SCREEN_HEIGHT * SCREEN_WIDTH
call ByteFill
ld a, $7f
hlcoord 0, 4
ld bc, (SCREEN_HEIGHT - 4) * SCREEN_WIDTH
call ByteFill
hlcoord 0, 4
ld a, $24
call DrawCreditsBorder
hlcoord 0, 17
ld a, $20
call DrawCreditsBorder
hlcoord 0, 0, wAttrmap
ld bc, 4 * SCREEN_WIDTH
xor a
call ByteFill
hlcoord 0, 4, wAttrmap
ld bc, SCREEN_WIDTH
ld a, $1
call ByteFill
hlcoord 0, 5, wAttrmap
ld bc, 12 * SCREEN_WIDTH
ld a, $2
call ByteFill
hlcoord 0, 17, wAttrmap
ld bc, SCREEN_WIDTH
ld a, $1
call ByteFill
call WaitBGMap2
xor a
ldh [hBGMapMode], a
ldh [hBGMapAddress], a
hlcoord 0, 0
call .InitTopPortion
call WaitBGMap2
ret
.InitTopPortion:
ld b, 5
.outer_loop
push hl
ld de, SCREEN_WIDTH - 3
ld c, 4
xor a
.inner_loop
rept 3
ld [hli], a
inc a
endr
ld [hl], a
inc a
add hl, de
dec c
jr nz, .inner_loop
pop hl
rept 4
inc hl
endr
dec b
jr nz, .outer_loop
ret
DrawCreditsBorder:
ld c, SCREEN_WIDTH / 4
.loop
push af
rept 3
ld [hli], a
inc a
endr
ld [hli], a
pop af
dec c
jr nz, .loop
ret
GetCreditsPalette:
call .GetPalAddress
push hl
ld a, 0
call .UpdatePals
pop hl
ret
.GetPalAddress:
; Each set of palette data is 24 bytes long.
ld a, [wCreditsBorderMon] ; scene
and %11
add a
add a ; * 8
add a
ld e, a
ld d, 0
ld hl, CreditsPalettes
add hl, de
add hl, de ; * 3
add hl, de
ret
.UpdatePals:
; Update the first three colors in both palette buffers.
push af
push hl
add LOW(wBGPals1)
ld e, a
ld a, 0
adc HIGH(wBGPals1)
ld d, a
ld bc, 24
call CopyBytes
pop hl
pop af
add LOW(wBGPals2)
ld e, a
ld a, 0
adc HIGH(wBGPals2)
ld d, a
ld bc, 24
call CopyBytes
ret
CreditsPalettes:
INCLUDE "gfx/credits/credits.pal"
Credits_LoadBorderGFX:
ld hl, wCreditsBorderFrame
ld a, [hl]
cp $ff
jr z, .init
and %11
ld e, a
inc a
and %11
ld [hl], a
ld a, [wCreditsBorderMon]
and %11
add a
add a
add e
add a
ld e, a
ld d, 0
ld hl, .Frames
add hl, de
ld a, [hli]
ld h, [hl]
ld l, a
ret
.init
ld hl, wCreditsBlankFrame2bpp
ret
.Frames:
dw CreditsPichuGFX
dw CreditsPichuGFX + 16 tiles
dw CreditsPichuGFX + 32 tiles
dw CreditsPichuGFX + 48 tiles
dw CreditsSmoochumGFX
dw CreditsSmoochumGFX + 16 tiles
dw CreditsSmoochumGFX + 32 tiles
dw CreditsSmoochumGFX + 48 tiles
dw CreditsDittoGFX
dw CreditsDittoGFX + 16 tiles
dw CreditsDittoGFX + 32 tiles
dw CreditsDittoGFX + 48 tiles
dw CreditsIgglybuffGFX
dw CreditsIgglybuffGFX + 16 tiles
dw CreditsIgglybuffGFX + 32 tiles
dw CreditsIgglybuffGFX + 48 tiles
Credits_TheEnd:
ld a, $40
hlcoord 6, 9
call .Load
hlcoord 6, 10
.Load:
ld c, 8
.loop
ld [hli], a
inc a
dec c
jr nz, .loop
ret
CreditsBorderGFX: INCBIN "gfx/credits/border.2bpp"
CreditsMonsGFX: ; used only for BANK(CreditsMonsGFX)
CreditsPichuGFX: INCBIN "gfx/credits/pichu.2bpp"
CreditsSmoochumGFX: INCBIN "gfx/credits/smoochum.2bpp"
CreditsDittoGFX: INCBIN "gfx/credits/ditto.2bpp"
CreditsIgglybuffGFX: INCBIN "gfx/credits/igglybuff.2bpp"
INCLUDE "data/credits_script.asm"
INCLUDE "data/credits_strings.asm"

View file

@ -0,0 +1,360 @@
EvolutionAnimation:
push hl
push de
push bc
ld a, [wCurSpecies]
push af
ldh a, [rOBP0]
push af
ld a, [wBaseSpecies]
push af
call .EvolutionAnimation
pop af
ld [wBaseSpecies], a
pop af
ldh [rOBP0], a
pop af
ld [wCurSpecies], a
pop bc
pop de
pop hl
ld a, [wEvolutionCanceled]
and a
ret z
scf
ret
.EvolutionAnimation:
ld a, %11100100
ldh [rOBP0], a
ld de, MUSIC_NONE
call PlayMusic
farcall ClearSpriteAnims
ld de, .GFX
ld hl, vTiles0
lb bc, BANK(.GFX), 8
call Request2bpp
xor a
ld [wLowHealthAlarm], a
call WaitBGMap
xor a
ldh [hBGMapMode], a
ld a, [wEvolutionOldSpecies]
ld [wPlayerHPPal], a
ld c, FALSE
call .GetSGBLayout
ld a, [wEvolutionOldSpecies]
ld [wCurPartySpecies], a
ld [wCurSpecies], a
call .PlaceFrontpic
ld de, vTiles2
ld hl, vTiles2 tile $31
ld bc, 7 * 7
call Request2bpp
ld a, 7 * 7
ld [wEvolutionPicOffset], a
call .ReplaceFrontpic
ld a, [wEvolutionNewSpecies]
ld [wCurPartySpecies], a
ld [wCurSpecies], a
call .LoadFrontpic
ld a, [wEvolutionOldSpecies]
ld [wCurPartySpecies], a
ld [wCurSpecies], a
ld a, 1
ldh [hBGMapMode], a
call .check_statused
jr c, .skip_cry
ld a, [wEvolutionOldSpecies]
call PlayMonCry
.skip_cry
ld de, MUSIC_EVOLUTION
call PlayMusic
ld c, 80
call DelayFrames
ld c, TRUE
call .GetSGBLayout
call .AnimationSequence
jr c, .cancel_evo
ld a, -7 * 7
ld [wEvolutionPicOffset], a
call .ReplaceFrontpic
xor a
ld [wEvolutionCanceled], a
ld a, [wEvolutionNewSpecies]
ld [wPlayerHPPal], a
ld c, FALSE
call .GetSGBLayout
call .PlayEvolvedSFX
farcall ClearSpriteAnims
call .check_statused
jr c, .no_anim
ld a, [wBoxAlignment]
push af
ld a, $1
ld [wBoxAlignment], a
ld a, [wCurPartySpecies]
push af
ld a, [wPlayerHPPal]
ld [wCurPartySpecies], a
hlcoord 7, 2
ld d, $0
ld e, ANIM_MON_EVOLVE
predef AnimateFrontpic
pop af
ld [wCurPartySpecies], a
pop af
ld [wBoxAlignment], a
ret
.no_anim
ret
.cancel_evo
ld a, TRUE
ld [wEvolutionCanceled], a
ld a, [wEvolutionOldSpecies]
ld [wPlayerHPPal], a
ld c, FALSE
call .GetSGBLayout
call .PlayEvolvedSFX
farcall ClearSpriteAnims
call .check_statused
ret c
ld a, [wPlayerHPPal]
call PlayMonCry
ret
.GetSGBLayout:
ld b, SCGB_EVOLUTION
jp GetSGBLayout
.PlaceFrontpic:
call GetBaseData
hlcoord 7, 2
jp PrepMonFrontpic
.LoadFrontpic:
call GetBaseData
ld a, $1
ld [wBoxAlignment], a
ld de, vTiles2
predef GetAnimatedFrontpic
xor a
ld [wBoxAlignment], a
ret
.AnimationSequence:
call ClearJoypad
lb bc, 1, 2 * 7 ; flash b times, wait c frames in between
.loop
push bc
call .WaitFrames_CheckPressedB
pop bc
jr c, .exit_sequence
push bc
call .Flash
pop bc
inc b
dec c
dec c
jr nz, .loop
and a
ret
.exit_sequence
scf
ret
.Flash:
ld a, -7 * 7 ; new stage
ld [wEvolutionPicOffset], a
call .ReplaceFrontpic
ld a, 7 * 7 ; previous stage
ld [wEvolutionPicOffset], a
call .ReplaceFrontpic
dec b
jr nz, .Flash
ret
.ReplaceFrontpic:
push bc
xor a
ldh [hBGMapMode], a
hlcoord 7, 2
lb bc, 7, 7
ld de, SCREEN_WIDTH - 7
.loop1
push bc
.loop2
ld a, [wEvolutionPicOffset]
add [hl]
ld [hli], a
dec c
jr nz, .loop2
pop bc
add hl, de
dec b
jr nz, .loop1
ld a, $1
ldh [hBGMapMode], a
call WaitBGMap
pop bc
ret
.WaitFrames_CheckPressedB:
call DelayFrame
push bc
call JoyTextDelay
ldh a, [hJoyDown]
pop bc
and B_BUTTON
jr nz, .pressed_b
.loop3
dec c
jr nz, .WaitFrames_CheckPressedB
and a
ret
.pressed_b
ld a, [wForceEvolution]
and a
jr nz, .loop3
scf
ret
.check_statused
ld a, [wCurPartyMon]
ld hl, wPartyMon1Species
call GetPartyLocation
ld b, h
ld c, l
farcall CheckFaintedFrzSlp
ret
.PlayEvolvedSFX:
ld a, [wEvolutionCanceled]
and a
ret nz
ld de, SFX_EVOLVED
call PlaySFX
ld hl, wJumptableIndex
ld a, [hl]
push af
ld [hl], $0
.loop4
call .balls_of_light
jr nc, .done
call .AnimateBallsOfLight
jr .loop4
.done
ld c, 32
.loop5
call .AnimateBallsOfLight
dec c
jr nz, .loop5
pop af
ld [wJumptableIndex], a
ret
.balls_of_light
ld hl, wJumptableIndex
ld a, [hl]
cp 32
ret nc
ld d, a
inc [hl]
and $1
jr nz, .done_balls
ld e, $0
call .GenerateBallOfLight
ld e, $10
call .GenerateBallOfLight
.done_balls
scf
ret
.GenerateBallOfLight:
push de
depixel 9, 11
ld a, SPRITE_ANIM_INDEX_EVOLUTION_BALL_OF_LIGHT
call InitSpriteAnimStruct
ld hl, SPRITEANIMSTRUCT_JUMPTABLE_INDEX
add hl, bc
ld a, [wJumptableIndex]
and %1110
sla a
pop de
add e
ld [hl], a
ld hl, SPRITEANIMSTRUCT_TILE_ID
add hl, bc
ld [hl], $0
ld hl, SPRITEANIMSTRUCT_VAR1
add hl, bc
ld [hl], $10
ret
.AnimateBallsOfLight:
push bc
callfar PlaySpriteAnimations
; a = (([hVBlankCounter] + 4) / 2) % NUM_PALETTES
ldh a, [hVBlankCounter]
and %1110
srl a
inc a
inc a
and $7
ld b, a
ld hl, wShadowOAMSprite00Attributes
ld c, NUM_SPRITE_OAM_STRUCTS
.loop6
ld a, [hl]
or b
ld [hli], a ; attributes
rept SPRITEOAMSTRUCT_LENGTH - 1
inc hl
endr
dec c
jr nz, .loop6
pop bc
call DelayFrame
ret
.GFX:
INCBIN "gfx/evo/bubble_large.2bpp"
INCBIN "gfx/evo/bubble.2bpp"

133
engine/movie/gbc_only.asm Normal file
View file

@ -0,0 +1,133 @@
GBCOnlyScreen:
ldh a, [hCGB]
and a
ret nz
ld de, MUSIC_NONE
call PlayMusic
call ClearTilemap
ld hl, GBCOnlyGFX
ld de, wGBCOnlyDecompressBuffer
ldh a, [rSVBK]
push af
ld a, 0 ; this has the same effect as selecting bank 1
ldh [rSVBK], a
call Decompress
pop af
ldh [rSVBK], a
ld de, wGBCOnlyDecompressBuffer
ld hl, vTiles2
lb bc, BANK(GBCOnlyGFX), 84
call Get2bpp
ld de, Font
ld hl, vTiles1
lb bc, BANK(Font), $80
call Get1bpp
call DrawGBCOnlyScreen
call WaitBGMap
; better luck next time
.loop
call DelayFrame
jr .loop
DrawGBCOnlyScreen:
call DrawGBCOnlyBorder
; Pokemon
hlcoord 3, 2
ld b, 14
ld c, 4
ld a, $8
call DrawGBCOnlyGraphic
; Crystal
hlcoord 5, 6
ld b, 10
ld c, 2
ld a, $40
call DrawGBCOnlyGraphic
ld de, GBCOnlyString
hlcoord 1, 10
call PlaceString
ret
DrawGBCOnlyBorder:
hlcoord 0, 0
ld [hl], 0 ; top-left
inc hl
ld a, 1 ; top
call .FillRow
ld [hl], 2 ; top-right
hlcoord 0, 1
ld a, 3 ; left
call .FillColumn
hlcoord 19, 1
ld a, 4 ; right
call .FillColumn
hlcoord 0, 17
ld [hl], 5 ; bottom-left
inc hl
ld a, 6 ; bottom
call .FillRow
ld [hl], 7 ; bottom-right
ret
.FillRow:
ld c, SCREEN_WIDTH - 2
.next_column
ld [hli], a
dec c
jr nz, .next_column
ret
.FillColumn:
ld de, SCREEN_WIDTH
ld c, SCREEN_HEIGHT - 2
.next_row
ld [hl], a
add hl, de
dec c
jr nz, .next_row
ret
DrawGBCOnlyGraphic:
ld de, SCREEN_WIDTH
.y
push bc
push hl
.x
ld [hli], a
inc a
dec b
jr nz, .x
pop hl
add hl, de
pop bc
dec c
jr nz, .y
ret
GBCOnlyString:
db "This Game Pak is"
next "designed only for"
next "use on the"
next "Game Boy Color.@"
GBCOnlyGFX:
INCBIN "gfx/sgb/gbc_only.2bpp.lz"

View file

@ -0,0 +1,78 @@
InitDisplayForHallOfFame:
call ClearBGPalettes
call ClearTilemap
call ClearSprites
call DisableLCD
call LoadStandardFont
call LoadFontsBattleExtra
hlbgcoord 0, 0
ld bc, vBGMap1 - vBGMap0
ld a, " "
call ByteFill
hlcoord 0, 0, wAttrmap
ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
xor a
call ByteFill
xor a
ldh [hSCY], a
ldh [hSCX], a
call EnableLCD
ld hl, .SavingRecordText
call PrintText
call WaitBGMap2
call SetPalettes
ret
.SavingRecordText:
text_far _SavingRecordText
text_end
InitDisplayForRedCredits:
call ClearBGPalettes
call ClearTilemap
call ClearSprites
call DisableLCD
call LoadStandardFont
call LoadFontsBattleExtra
hlbgcoord 0, 0
ld bc, vBGMap1 - vBGMap0
ld a, " "
call ByteFill
hlcoord 0, 0, wAttrmap
ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
xor a
call ByteFill
ld hl, wBGPals1
ld c, 4 tiles
.load_white_palettes
ld a, LOW(PALRGB_WHITE)
ld [hli], a
ld a, HIGH(PALRGB_WHITE)
ld [hli], a
dec c
jr nz, .load_white_palettes
xor a
ldh [hSCY], a
ldh [hSCX], a
call EnableLCD
call WaitBGMap2
call SetPalettes
ret
ResetDisplayBetweenHallOfFameMons:
ldh a, [rSVBK]
push af
ld a, BANK(wDecompressScratch)
ldh [rSVBK], a
ld hl, wDecompressScratch
ld bc, wScratchAttrmap - wDecompressScratch
ld a, " "
call ByteFill
hlbgcoord 0, 0
ld de, wDecompressScratch
ld b, 0
ld c, 4 tiles
call Request2bpp
pop af
ldh [rSVBK], a
ret

1777
engine/movie/intro.asm Normal file

File diff suppressed because it is too large Load diff

349
engine/movie/splash.asm Normal file
View file

@ -0,0 +1,349 @@
SplashScreen:
; Play the copyright screen and GameFreak Presents sequence.
; Return carry if user cancels animation by pressing a button.
; Reinitialize everything
ld de, MUSIC_NONE
call PlayMusic
call ClearBGPalettes
call ClearTilemap
ld a, HIGH(vBGMap0)
ldh [hBGMapAddress + 1], a
xor a ; LOW(vBGMap0)
ldh [hBGMapAddress], a
ldh [hJoyDown], a
ldh [hSCX], a
ldh [hSCY], a
ld a, SCREEN_HEIGHT_PX
ldh [hWY], a
call WaitBGMap
ld b, SCGB_GAMEFREAK_LOGO
call GetSGBLayout
call SetPalettes
ld c, 10
call DelayFrames
; Draw copyright screen
callfar Copyright
call WaitBGMap
ld c, 100
call DelayFrames
call ClearTilemap
; Stop here if not in GBC mode
farcall GBCOnlyScreen
; Play GameFreak logo animation
call GameFreakPresentsInit
.joy_loop
call JoyTextDelay
ldh a, [hJoyLast]
and BUTTONS
jr nz, .pressed_button
ld a, [wJumptableIndex]
bit 7, a
jr nz, .finish
call GameFreakPresentsScene
farcall PlaySpriteAnimations
call DelayFrame
jr .joy_loop
.pressed_button
call GameFreakPresentsEnd
scf
ret
.finish
call GameFreakPresentsEnd
and a
ret
GameFreakPresentsInit:
ld de, GameFreakLogoGFX
ld hl, vTiles2
lb bc, BANK(GameFreakLogoGFX), 28
call Get1bpp
ldh a, [rSVBK]
push af
ld a, BANK(wDecompressScratch)
ldh [rSVBK], a
ld hl, GameFreakDittoGFX
ld de, wDecompressScratch
ld a, BANK(GameFreakDittoGFX)
call FarDecompress
ld hl, vTiles0
ld de, wDecompressScratch
lb bc, 1, 8 tiles
call Request2bpp
ld hl, vTiles1
ld de, wDecompressScratch + $80 tiles
lb bc, 1, 8 tiles
call Request2bpp
pop af
ldh [rSVBK], a
farcall ClearSpriteAnims
depixel 10, 11, 4, 0
ld a, SPRITE_ANIM_INDEX_GAMEFREAK_LOGO
call InitSpriteAnimStruct
ld hl, SPRITEANIMSTRUCT_YOFFSET
add hl, bc
ld [hl], 160
ld hl, SPRITEANIMSTRUCT_VAR1
add hl, bc
ld [hl], 96
ld hl, SPRITEANIMSTRUCT_VAR2
add hl, bc
ld [hl], 48
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, 144
ldh [hWY], a
lb de, %11100100, %11100100
call DmgToCgbObjPals
ret
GameFreakPresentsEnd:
farcall ClearSpriteAnims
call ClearTilemap
call ClearSprites
ld c, 16
call DelayFrames
ret
GameFreakPresentsScene:
jumptable .scenes, wJumptableIndex
.scenes
dw GameFreakPresents_WaitSpriteAnim
dw GameFreakPresents_PlaceGameFreak
dw GameFreakPresents_PlacePresents
dw GameFreakPresents_WaitForTimer
GameFreakPresents_NextScene:
ld hl, wJumptableIndex
inc [hl]
ret
GameFreakPresents_WaitSpriteAnim:
ret
GameFreakPresents_PlaceGameFreak:
ld hl, wIntroSceneTimer
ld a, [hl]
cp 32
jr nc, .PlaceGameFreak
inc [hl]
ret
.PlaceGameFreak:
ld [hl], 0
ld hl, .game_freak
decoord 5, 10
ld bc, .end - .game_freak
call CopyBytes
call GameFreakPresents_NextScene
ld de, SFX_GAME_FREAK_PRESENTS
call PlaySFX
ret
.game_freak
db $00, $01, $02, $03, $0d, $04, $05, $03, $01, $06
.end
db "@"
GameFreakPresents_PlacePresents:
ld hl, wIntroSceneTimer
ld a, [hl]
cp 64
jr nc, .place_presents
inc [hl]
ret
.place_presents
ld [hl], 0
ld hl, .presents
decoord 7, 11
ld bc, .end - .presents
call CopyBytes
call GameFreakPresents_NextScene
ret
.presents
db $07, $08, $09, $0a, $0b, $0c
.end
db "@"
GameFreakPresents_WaitForTimer:
ld hl, wIntroSceneTimer
ld a, [hl]
cp 128
jr nc, .finish
inc [hl]
ret
.finish
ld hl, wJumptableIndex
set 7, [hl]
ret
GameFreakLogoSpriteAnim:
ld hl, SPRITEANIMSTRUCT_JUMPTABLE_INDEX
add hl, bc
ld e, [hl]
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 GameFreakLogo_Init
dw GameFreakLogo_Bounce
dw GameFreakLogo_Ditto
dw GameFreakLogo_Transform
dw GameFreakLogo_Done
GameFreakLogo_Init:
ld hl, SPRITEANIMSTRUCT_JUMPTABLE_INDEX
add hl, bc
inc [hl]
ret
GameFreakLogo_Bounce:
; Bounce with a height of 0C, 0C / 48 times.
; By default, this is twice, with a height of 96 pixels and 48 pixels.
; Sine offset starts at 48 (32+32/2, or pi+pi/2), so it starts at the maximum
; value of the sine wave (i.e. the top of the screen).
ld hl, SPRITEANIMSTRUCT_VAR1 ; jump height
add hl, bc
ld a, [hl]
and a
jr z, .done
; Load the sine offset, make sure it doesn't reach the negative part of the wave
ld d, a
ld hl, SPRITEANIMSTRUCT_VAR2 ; sine offset
add hl, bc
ld a, [hl]
and $3f ; full circle = 2*pi = 2*32
cp 32
jr nc, .no_negative
add 32
.no_negative
ld e, a
farcall BattleAnim_Sine_e ; e = d * sin(e * pi/32)
ld hl, SPRITEANIMSTRUCT_YOFFSET
add hl, bc
ld [hl], e
; Decrement the sine offset
ld hl, SPRITEANIMSTRUCT_VAR2 ; sine offset
add hl, bc
ld a, [hl]
dec [hl]
and $1f ; a%32 == 0
ret nz
; If the ditto's reached the ground, decrement the jump height and play the sfx
ld hl, SPRITEANIMSTRUCT_VAR1 ; jump height
add hl, bc
ld a, [hl]
sub 48
ld [hl], a
ld de, SFX_DITTO_BOUNCE
call PlaySFX
ret
.done
ld hl, SPRITEANIMSTRUCT_JUMPTABLE_INDEX
add hl, bc
inc [hl]
ld hl, SPRITEANIMSTRUCT_VAR2
add hl, bc
ld [hl], 0
ld de, SFX_DITTO_POP_UP
call PlaySFX
ret
GameFreakLogo_Ditto:
; Wait a little, then start transforming
ld hl, SPRITEANIMSTRUCT_VAR2 ; frame count
add hl, bc
ld a, [hl]
cp 32
jr nc, .start_transform
inc [hl]
ret
.start_transform
ld hl, SPRITEANIMSTRUCT_JUMPTABLE_INDEX
add hl, bc
inc [hl]
ld hl, SPRITEANIMSTRUCT_VAR2
add hl, bc
ld [hl], 0
ld de, SFX_DITTO_TRANSFORM
call PlaySFX
ret
GameFreakLogo_Transform:
ld hl, SPRITEANIMSTRUCT_VAR2 ; frame count
add hl, bc
ld a, [hl]
cp 64
jr z, .done
inc [hl]
; Fade ditto's palettes while it's transforming
srl a
srl a
ld e, a
ld d, 0
ld hl, GameFreakDittoPaletteFade
add hl, de
add hl, de
ldh a, [rSVBK]
push af
ld a, BANK(wOBPals2)
ldh [rSVBK], a
ld a, [hli]
ld [wOBPals2 + 12], a
ld a, [hli]
ld [wOBPals2 + 13], a
pop af
ldh [rSVBK], a
ld a, TRUE
ldh [hCGBPalUpdate], a
ret
.done
ld hl, SPRITEANIMSTRUCT_JUMPTABLE_INDEX
add hl, bc
inc [hl]
call GameFreakPresents_NextScene
GameFreakLogo_Done:
ret
GameFreakDittoPaletteFade:
INCLUDE "gfx/splash/ditto_fade.pal"
GameFreakLogoGFX:
INCBIN "gfx/splash/gamefreak_presents.1bpp"
INCBIN "gfx/splash/gamefreak_logo.1bpp"

374
engine/movie/title.asm Normal file
View file

@ -0,0 +1,374 @@
_TitleScreen:
call ClearBGPalettes
call ClearSprites
call ClearTilemap
; Turn BG Map update off
xor a
ldh [hBGMapMode], a
; Reset timing variables
ld hl, wJumptableIndex
ld [hli], a ; wJumptableIndex
ld [hli], a ; wTitleScreenSelectedOption
ld [hli], a ; wTitleScreenTimer
ld [hl], a ; wTitleScreenTimer + 1
; Turn LCD off
call DisableLCD
; VRAM bank 1
ld a, 1
ldh [rVBK], a
; Decompress running Suicune gfx
ld hl, TitleSuicuneGFX
ld de, vTiles1
call Decompress
; Clear screen palettes
hlbgcoord 0, 0
ld bc, 20 * BG_MAP_WIDTH
xor a
call ByteFill
; Fill tile palettes:
; BG Map 1:
; line 0 (copyright)
hlbgcoord 0, 0, vBGMap1
ld bc, BG_MAP_WIDTH
ld a, 7 ; palette
call ByteFill
; BG Map 0:
; Apply logo gradient:
; lines 3-4
hlbgcoord 0, 3
ld bc, 2 * BG_MAP_WIDTH
ld a, 2
call ByteFill
; line 5
hlbgcoord 0, 5
ld bc, BG_MAP_WIDTH
ld a, 3
call ByteFill
; line 6
hlbgcoord 0, 6
ld bc, BG_MAP_WIDTH
ld a, 4
call ByteFill
; line 7
hlbgcoord 0, 7
ld bc, BG_MAP_WIDTH
ld a, 5
call ByteFill
; lines 8-9
hlbgcoord 0, 8
ld bc, 2 * BG_MAP_WIDTH
ld a, 6
call ByteFill
; 'CRYSTAL VERSION'
hlbgcoord 5, 9
ld bc, 11 ; length of version text
ld a, 1
call ByteFill
; Suicune gfx
hlbgcoord 0, 12
ld bc, 6 * BG_MAP_WIDTH ; the rest of the screen
ld a, 0 | VRAM_BANK_1
call ByteFill
; Back to VRAM bank 0
ld a, 0
ldh [rVBK], a
; Decompress logo
ld hl, TitleLogoGFX
ld de, vTiles1
call Decompress
; Decompress background crystal
ld hl, TitleCrystalGFX
ld de, vTiles0
call Decompress
; Clear screen tiles
hlbgcoord 0, 0
ld bc, 64 * BG_MAP_WIDTH
ld a, " "
call ByteFill
; Draw Pokemon logo
hlcoord 0, 3
lb bc, 7, 20
ld d, $80
ld e, 20
call DrawTitleGraphic
; Draw copyright text
hlbgcoord 3, 0, vBGMap1
lb bc, 1, 13
ld d, $c
ld e, 16
call DrawTitleGraphic
; Initialize running Suicune?
ld d, $0
call LoadSuicuneFrame
; Initialize background crystal
call InitializeBackground
; Update palette colors
ldh a, [rSVBK]
push af
ld a, BANK(wBGPals1)
ldh [rSVBK], a
ld hl, TitleScreenPalettes
ld de, wBGPals1
ld bc, 16 palettes
call CopyBytes
ld hl, TitleScreenPalettes
ld de, wBGPals2
ld bc, 16 palettes
call CopyBytes
pop af
ldh [rSVBK], a
; LY/SCX trickery starts here
ldh a, [rSVBK]
push af
ld a, BANK(wLYOverrides)
ldh [rSVBK], a
; Make alternating lines come in from opposite sides
; (This part is actually totally pointless, you can't
; see anything until these values are overwritten!)
ld b, 80 / 2 ; alternate for 80 lines
ld hl, wLYOverrides
.loop
; $00 is the middle position
ld [hl], +112 ; coming from the left
inc hl
ld [hl], -112 ; coming from the right
inc hl
dec b
jr nz, .loop
; Make sure the rest of the buffer is empty
ld hl, wLYOverrides + 80
xor a
ld bc, wLYOverridesEnd - (wLYOverrides + 80)
call ByteFill
; Let LCD Stat know we're messing around with SCX
ld a, LOW(rSCX)
ldh [hLCDCPointer], a
pop af
ldh [rSVBK], a
; Reset audio
call ChannelsOff
call EnableLCD
; Set sprite size to 8x16
ldh a, [rLCDC]
set rLCDC_SPRITE_SIZE, a
ldh [rLCDC], a
ld a, +112
ldh [hSCX], a
ld a, 8
ldh [hSCY], a
ld a, 7
ldh [hWX], a
ld a, -112
ldh [hWY], a
ld a, TRUE
ldh [hCGBPalUpdate], a
; Update BG Map 0 (bank 0)
ldh [hBGMapMode], a
xor a
ld [wSuicuneFrame], a
; Play starting sound effect
call SFXChannelsOff
ld de, SFX_TITLE_SCREEN_ENTRANCE
call PlaySFX
ret
SuicuneFrameIterator:
ld hl, wSuicuneFrame
ld a, [hl]
ld c, a
inc [hl]
; Only do this once every eight frames
and %111
ret nz
ld a, c
and %11000
sla a
swap a
ld e, a
ld d, 0
ld hl, .Frames
add hl, de
ld d, [hl]
xor a
ldh [hBGMapMode], a
call LoadSuicuneFrame
ld a, $1
ldh [hBGMapMode], a
ld a, $3
ldh [hBGMapThird], a
ret
.Frames:
db $80 ; vTiles3 tile $80
db $88 ; vTiles3 tile $88
db $00 ; vTiles5 tile $00
db $08 ; vTiles5 tile $08
LoadSuicuneFrame:
hlcoord 6, 12
ld b, 6
.bgrows
ld c, 8
.col
ld a, d
ld [hli], a
inc d
dec c
jr nz, .col
ld a, SCREEN_WIDTH - 8
add l
ld l, a
ld a, 0
adc h
ld h, a
ld a, 8
add d
ld d, a
dec b
jr nz, .bgrows
ret
DrawTitleGraphic:
; input:
; hl: draw location
; b: height
; c: width
; d: tile to start drawing from
; e: number of tiles to advance for each bgrows
.bgrows
push de
push bc
push hl
.col
ld a, d
ld [hli], a
inc d
dec c
jr nz, .col
pop hl
ld bc, SCREEN_WIDTH
add hl, bc
pop bc
pop de
ld a, e
add d
ld d, a
dec b
jr nz, .bgrows
ret
InitializeBackground:
ld hl, wShadowOAMSprite00
ld d, -$22
ld e, $0
ld c, 5
.loop
push bc
call .InitColumn
pop bc
ld a, $10
add d
ld d, a
dec c
jr nz, .loop
ret
.InitColumn:
ld c, $6
ld b, $40
.loop2
ld a, d
ld [hli], a ; y
ld a, b
ld [hli], a ; x
add $8
ld b, a
ld a, e
ld [hli], a ; tile id
inc e
inc e
ld a, 0 | PRIORITY
ld [hli], a ; attributes
dec c
jr nz, .loop2
ret
AnimateTitleCrystal:
; Move the title screen crystal downward until it's fully visible
; Stop at y=6
; y is really from the bottom of the sprite, which is two tiles high
ld hl, wShadowOAMSprite00YCoord
ld a, [hl]
cp 6 + 2 * TILE_WIDTH
ret z
; Move all 30 parts of the crystal down by 2
ld c, 30
.loop
ld a, [hl]
add 2
ld [hli], a ; y
rept SPRITEOAMSTRUCT_LENGTH - 1
inc hl
endr
dec c
jr nz, .loop
ret
TitleSuicuneGFX:
INCBIN "gfx/title/suicune.2bpp.lz"
TitleLogoGFX:
INCBIN "gfx/title/logo.2bpp.lz"
TitleCrystalGFX:
INCBIN "gfx/title/crystal.2bpp.lz"
TitleScreenPalettes:
INCLUDE "gfx/title/title.pal"

File diff suppressed because it is too large Load diff