diff options
author | Diegoisawesome <diego@domoreaweso.me> | 2018-02-07 18:06:59 -0600 |
---|---|---|
committer | Diegoisawesome <diego@domoreaweso.me> | 2018-02-07 18:06:59 -0600 |
commit | 772fd47564da4d2c4072b83e43a9cc28e62ce5bb (patch) | |
tree | b81a93d022488ed5a71ce0ac80ee4dd1b5662ac9 /src/title_screen.c | |
parent | 5db765a475bf401417bbf7a3ca8b89dc0425f793 (diff) | |
parent | 48e63979c8a131bc059974194bd548f60dcdd24c (diff) |
Merge branch 'master' of https://github.com/pret/pokeemerald into menu
Diffstat (limited to 'src/title_screen.c')
-rw-r--r-- | src/title_screen.c | 783 |
1 files changed, 783 insertions, 0 deletions
diff --git a/src/title_screen.c b/src/title_screen.c new file mode 100644 index 000000000..4e25c8152 --- /dev/null +++ b/src/title_screen.c @@ -0,0 +1,783 @@ +#include "global.h" +#include "title_screen.h" +#include "sprite.h" +#include "gba/m4a_internal.h" +#include "clear_save_data_menu.h" +#include "decompress.h" +#include "event_data.h" +#include "intro.h" +#include "m4a.h" +#include "main.h" +#include "main_menu.h" +#include "palette.h" +#include "reset_rtc_screen.h" +#include "berry_fix_program.h" +#include "sound.h" +#include "sprite.h" +#include "task.h" +#include "scanline_effect.h" +#include "gpu_regs.h" +#include "trig.h" +#include "constants/rgb.h" + +#define VERSION_BANNER_SHAPE 1 +#define VERSION_BANNER_RIGHT_TILEOFFSET 64 +#define VERSION_BANNER_BYTES 0x1000 +#define VERSION_BANNER_LEFT_X 98 +#define VERSION_BANNER_RIGHT_X 162 +#define VERSION_BANNER_Y 2 +#define VERSION_BANNER_Y_GOAL 66 +#define START_BANNER_X 128 + +#define CLEAR_SAVE_BUTTON_COMBO (B_BUTTON | SELECT_BUTTON | DPAD_UP) +#define RESET_RTC_BUTTON_COMBO (B_BUTTON | SELECT_BUTTON | DPAD_LEFT) +#define BERRY_UPDATE_BUTTON_COMBO (B_BUTTON | SELECT_BUTTON) +#define A_B_START_SELECT (A_BUTTON | B_BUTTON | START_BUTTON | SELECT_BUTTON) + +extern struct MusicPlayerInfo gMPlayInfo_BGM; +extern u16 gBattle_BG1_X; +extern u16 gBattle_BG1_Y; + +extern const u8 gTitleScreenEmeraldVersionGfx[]; +extern const u8 gTitleScreenPressStartGfx[]; +extern const u8 gTitleScreenPokemonLogoGfx[]; +extern const u8 gUnknown_08DE0644[]; +extern const u8 gUnknown_08DDE458[]; +extern const u16 gTitleScreenBgPalettes[]; +extern const u16 gTitleScreenPressStartPal[]; +extern const u16 gTitleScreenEmeraldVersionPal[]; + +// this file's functions +static void MainCB2(void); +static void Task_TitleScreenPhase1(u8); +static void Task_TitleScreenPhase2(u8); +static void Task_TitleScreenPhase3(u8); +static void CB2_GoToMainMenu(void); +static void CB2_GoToClearSaveDataScreen(void); +static void CB2_GoToResetRtcScreen(void); +static void CB2_GoToBerryFixScreen(void); +static void CB2_GoToCopyrightScreen(void); +static void UpdateLegendaryMarkingColor(u8); + +static void SpriteCB_VersionBannerLeft(struct Sprite *sprite); +static void SpriteCB_VersionBannerRight(struct Sprite *sprite); +static void SpriteCB_PressStartCopyrightBanner(struct Sprite *sprite); +static void SpriteCB_PokemonLogoShine(struct Sprite *sprite); + +// const rom data +static const u16 sUnusedUnknownPal[] = INCBIN_U16("graphics/title_screen/unk_853EF78.gbapal"); + +static const u8 sTitleScreenRayquazaGfx[] = INCBIN_U8("graphics/title_screen/rayquaza.4bpp.lz"); +static const u8 sTitleScreenRayquazaTilemap[] = INCBIN_U8("graphics/title_screen/rayquaza.bin.lz"); +static const u8 sTitleScreenLogoShineGfx[] = INCBIN_U8("graphics/title_screen/logo_shine.4bpp.lz"); +static const u8 sTitleScreenCloudsGfx[] = INCBIN_U8("graphics/title_screen/clouds.4bpp.lz"); + +const u16 gUnknown_0853FF70[] = +{ + 0x0010, 0x0110, 0x0210, 0x0310, 0x0410, 0x0510, 0x0610, 0x0710, + 0x0810, 0x0910, 0x0a10, 0x0b10, 0x0c10, 0x0d10, 0x0e10, 0x0f10, + 0x100f, 0x100e, 0x100d, 0x100c, 0x100b, 0x100a, 0x1009, 0x1008, + 0x1007, 0x1006, 0x1005, 0x1004, 0x1003, 0x1002, 0x1001, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, +}; + +static const struct OamData sVersionBannerLeftOamData = +{ + .y = 160, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 1, + .shape = VERSION_BANNER_SHAPE, + .x = 0, + .matrixNum = 0, + .size = 3, + .tileNum = 0, + .priority = 0, + .paletteNum = 0, + .affineParam = 0, +}; + +static const struct OamData sVersionBannerRightOamData = +{ + .y = 160, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 1, + .shape = VERSION_BANNER_SHAPE, + .x = 0, + .matrixNum = 0, + .size = 3, + .tileNum = 0, + .priority = 0, + .paletteNum = 0, + .affineParam = 0, +}; + +static const union AnimCmd sVersionBannerLeftAnimSequence[] = +{ + ANIMCMD_FRAME(0, 30), + ANIMCMD_END, +}; + +static const union AnimCmd sVersionBannerRightAnimSequence[] = +{ + ANIMCMD_FRAME(VERSION_BANNER_RIGHT_TILEOFFSET, 30), + ANIMCMD_END, +}; + +static const union AnimCmd *const sVersionBannerLeftAnimTable[] = +{ + sVersionBannerLeftAnimSequence, +}; + +static const union AnimCmd *const sVersionBannerRightAnimTable[] = +{ + sVersionBannerRightAnimSequence, +}; + +static const struct SpriteTemplate sVersionBannerLeftSpriteTemplate = +{ + .tileTag = 1000, + .paletteTag = 1000, + .oam = &sVersionBannerLeftOamData, + .anims = sVersionBannerLeftAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCB_VersionBannerLeft, +}; + +static const struct SpriteTemplate sVersionBannerRightSpriteTemplate = +{ + .tileTag = 1000, + .paletteTag = 1000, + .oam = &sVersionBannerRightOamData, + .anims = sVersionBannerRightAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCB_VersionBannerRight, +}; + +static const struct CompressedSpriteSheet sSpriteSheet_EmeraldVersion[] = +{ + {gTitleScreenEmeraldVersionGfx, VERSION_BANNER_BYTES, 1000}, + {NULL}, +}; + +static const struct OamData sOamData_CopyrightBanner = +{ + .y = 160, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = 1, + .x = 0, + .matrixNum = 0, + .size = 1, + .tileNum = 0, + .priority = 0, + .paletteNum = 0, + .affineParam = 0, +}; + +static const union AnimCmd sCopyrightBannerAnim0[] = +{ + ANIMCMD_FRAME(1, 4), + ANIMCMD_END, +}; +static const union AnimCmd sCopyrightBannerAnim1[] = +{ + ANIMCMD_FRAME(5, 4), + ANIMCMD_END, +}; +static const union AnimCmd sCopyrightBannerAnim2[] = +{ + ANIMCMD_FRAME(9, 4), + ANIMCMD_END, +}; +static const union AnimCmd sCopyrightBannerAnim3[] = +{ + ANIMCMD_FRAME(13, 4), + ANIMCMD_END, +}; +static const union AnimCmd sCopyrightBannerAnim4[] = +{ + ANIMCMD_FRAME(17, 4), + ANIMCMD_END, +}; +static const union AnimCmd sCopyrightBannerAnim5[] = +{ + ANIMCMD_FRAME(21, 4), + ANIMCMD_END, +}; +static const union AnimCmd sCopyrightBannerAnim6[] = +{ + ANIMCMD_FRAME(25, 4), + ANIMCMD_END, +}; +static const union AnimCmd sCopyrightBannerAnim7[] = +{ + ANIMCMD_FRAME(29, 4), + ANIMCMD_END, +}; +static const union AnimCmd sCopyrightBannerAnim8[] = +{ + ANIMCMD_FRAME(33, 4), + ANIMCMD_END, +}; +static const union AnimCmd sCopyrightBannerAnim9[] = +{ + ANIMCMD_FRAME(37, 4), + ANIMCMD_END, +}; + +static const union AnimCmd *const sStartCopyrightBannerAnimTable[] = +{ + sCopyrightBannerAnim0, + sCopyrightBannerAnim1, + sCopyrightBannerAnim2, + sCopyrightBannerAnim3, + sCopyrightBannerAnim4, + sCopyrightBannerAnim5, + sCopyrightBannerAnim6, + sCopyrightBannerAnim7, + sCopyrightBannerAnim8, + sCopyrightBannerAnim9, +}; + +static const struct SpriteTemplate sStartCopyrightBannerSpriteTemplate = +{ + .tileTag = 1001, + .paletteTag = 1001, + .oam = &sOamData_CopyrightBanner, + .anims = sStartCopyrightBannerAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCB_PressStartCopyrightBanner, +}; + +static const struct CompressedSpriteSheet sSpriteSheet_PressStart[] = +{ + {gTitleScreenPressStartGfx, 0x520, 1001}, + {NULL}, +}; + +static const struct SpritePalette sSpritePalette_PressStart[] = +{ + {gTitleScreenPressStartPal, 1001}, + {NULL}, +}; + +static const struct OamData sPokemonLogoShineOamData = +{ + .y = 160, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = 0, + .x = 0, + .matrixNum = 0, + .size = 3, + .tileNum = 0, + .priority = 0, + .paletteNum = 0, + .affineParam = 0, +}; + +static const union AnimCmd sPokemonLogoShineAnimSequence[] = +{ + ANIMCMD_FRAME(0, 4), + ANIMCMD_END, +}; + +static const union AnimCmd *const sPokemonLogoShineAnimTable[] = +{ + sPokemonLogoShineAnimSequence, +}; + +static const struct SpriteTemplate sPokemonLogoShineSpriteTemplate = +{ + .tileTag = 1002, + .paletteTag = 1001, + .oam = &sPokemonLogoShineOamData, + .anims = sPokemonLogoShineAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCB_PokemonLogoShine, +}; + +static const struct CompressedSpriteSheet sPokemonLogoShineSpriteSheet[] = +{ + {sTitleScreenLogoShineGfx, 0x800, 1002}, + {NULL}, +}; + +// code +static void SpriteCB_VersionBannerLeft(struct Sprite *sprite) +{ + if (gTasks[sprite->data[1]].data[1] != 0) + { + sprite->oam.objMode = 0; + sprite->pos1.y = VERSION_BANNER_Y_GOAL; + } + else + { + if (sprite->pos1.y != VERSION_BANNER_Y_GOAL) + sprite->pos1.y++; + if (sprite->data[0] != 0) + sprite->data[0]--; + SetGpuReg(REG_OFFSET_BLDALPHA, gUnknown_0853FF70[sprite->data[0]]); + } +} + +static void SpriteCB_VersionBannerRight(struct Sprite *sprite) +{ + if (gTasks[sprite->data[1]].data[1] != 0) + { + sprite->oam.objMode = 0; + sprite->pos1.y = VERSION_BANNER_Y_GOAL; + } + else + { + if (sprite->pos1.y != VERSION_BANNER_Y_GOAL) + sprite->pos1.y++; + } +} + +static void SpriteCB_PressStartCopyrightBanner(struct Sprite *sprite) +{ + if (sprite->data[0] == 1) + { + sprite->data[1]++; + // Alternate between hidden and shown every 16th frame + if (sprite->data[1] & 0x10) + sprite->invisible = FALSE; + else + sprite->invisible = TRUE; + } + else + { + sprite->invisible = FALSE; + } +} + +static void CreatePressStartBanner(s16 x, s16 y) +{ + u8 i; + u8 spriteId; + + x -= 64; + for (i = 0; i < 5; i++, x += 32) + { + spriteId = CreateSprite(&sStartCopyrightBannerSpriteTemplate, x, y, 0); + StartSpriteAnim(&gSprites[spriteId], i); + gSprites[spriteId].data[0] = 1; + } +} + +static void CreateCopyrightBanner(s16 x, s16 y) +{ + u8 i; + u8 spriteId; + + x -= 64; + for (i = 0; i < 5; i++, x += 32) + { + spriteId = CreateSprite(&sStartCopyrightBannerSpriteTemplate, x, y, 0); + StartSpriteAnim(&gSprites[spriteId], i + 5); + } +} + +static void SpriteCB_PokemonLogoShine(struct Sprite *sprite) +{ + if (sprite->pos1.x < 272) + { + if (sprite->data[0]) // Flash background + { + u16 backgroundColor; + + if (sprite->pos1.x < DISPLAY_WIDTH / 2) + { + // Brighten background color + if (sprite->data[1] < 31) + sprite->data[1]++; + if (sprite->data[1] < 31) + sprite->data[1]++; + } + else + { + // Darken background color + if (sprite->data[1] != 0) + sprite->data[1]--; + if (sprite->data[1] != 0) + sprite->data[1]--; + } + + backgroundColor = _RGB(sprite->data[1], sprite->data[1], sprite->data[1]); + if (sprite->pos1.x == DISPLAY_WIDTH / 2 + 12 + || sprite->pos1.x == DISPLAY_WIDTH / 2 + 16 + || sprite->pos1.x == DISPLAY_WIDTH / 2 + 20 + || sprite->pos1.x == DISPLAY_WIDTH / 2 + 24) + gPlttBufferFaded[0] = RGB(24, 31, 12); + else + gPlttBufferFaded[0] = backgroundColor; + } + sprite->pos1.x += 4; + } + else + { + gPlttBufferFaded[0] = RGB_BLACK; + DestroySprite(sprite); + } +} + +static void SpriteCB_PokemonLogoShine2(struct Sprite *sprite) +{ + if (sprite->pos1.x < 272) + sprite->pos1.x += 8; + else + DestroySprite(sprite); +} + +static void StartPokemonLogoShine(u8 flashBg) +{ + u8 spriteId; + + switch (flashBg) + { + case 0: + case 2: + spriteId = CreateSprite(&sPokemonLogoShineSpriteTemplate, 0, 68, 0); + gSprites[spriteId].oam.objMode = 2; + gSprites[spriteId].data[0] = flashBg; + break; + case 1: + spriteId = CreateSprite(&sPokemonLogoShineSpriteTemplate, 0, 68, 0); + gSprites[spriteId].oam.objMode = 2; + gSprites[spriteId].data[0] = flashBg; + gSprites[spriteId].invisible = TRUE; + + spriteId = CreateSprite(&sPokemonLogoShineSpriteTemplate, 0, 68, 0); + gSprites[spriteId].callback = SpriteCB_PokemonLogoShine2; + gSprites[spriteId].oam.objMode = 2; + + spriteId = CreateSprite(&sPokemonLogoShineSpriteTemplate, -80, 68, 0); + gSprites[spriteId].callback = SpriteCB_PokemonLogoShine2; + gSprites[spriteId].oam.objMode = 2; + break; + } +} + +static void VBlankCB(void) +{ + ScanlineEffect_InitHBlankDmaTransfer(); + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); + SetGpuReg(REG_OFFSET_BG1VOFS, gBattle_BG1_Y); +} + +#define tCounter data[0] +#define tSkipToNext data[1] + +void CB2_InitTitleScreen(void) +{ + switch (gMain.state) + { + default: + case 0: + SetVBlankCallback(NULL); + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + SetGpuReg(REG_OFFSET_BLDY, 0); + *((u16 *)PLTT) = RGB_WHITE; + SetGpuReg(REG_OFFSET_DISPCNT, 0); + SetGpuReg(REG_OFFSET_BG2CNT, 0); + SetGpuReg(REG_OFFSET_BG1CNT, 0); + SetGpuReg(REG_OFFSET_BG0CNT, 0); + SetGpuReg(REG_OFFSET_BG2HOFS, 0); + SetGpuReg(REG_OFFSET_BG2VOFS, 0); + SetGpuReg(REG_OFFSET_BG1HOFS, 0); + SetGpuReg(REG_OFFSET_BG1VOFS, 0); + SetGpuReg(REG_OFFSET_BG0HOFS, 0); + SetGpuReg(REG_OFFSET_BG0VOFS, 0); + DmaFill16(3, 0, (void *)VRAM, VRAM_SIZE); + DmaFill32(3, 0, (void *)OAM, OAM_SIZE); + DmaFill16(3, 0, (void *)(PLTT + 2), PLTT_SIZE - 2); + ResetPaletteFade(); + gMain.state = 1; + break; + case 1: + LZ77UnCompVram(gTitleScreenPokemonLogoGfx, (void *)VRAM); + LZ77UnCompVram(gUnknown_08DE0644, (void *)(VRAM + 0x4800)); + LoadPalette(gTitleScreenBgPalettes, 0, 0x1E0); + LZ77UnCompVram(sTitleScreenRayquazaGfx, (void *)(VRAM + 0x8000)); + LZ77UnCompVram(sTitleScreenRayquazaTilemap, (void *)(VRAM + 0xD000)); + LZ77UnCompVram(sTitleScreenCloudsGfx, (void *)(VRAM + 0xC000)); + LZ77UnCompVram(gUnknown_08DDE458, (void *)(VRAM + 0xD800)); + ScanlineEffect_Stop(); + ResetTasks(); + ResetSpriteData(); + FreeAllSpritePalettes(); + gReservedSpritePaletteCount = 9; + LoadCompressedObjectPic(&sSpriteSheet_EmeraldVersion[0]); + LoadCompressedObjectPic(&sSpriteSheet_PressStart[0]); + LoadCompressedObjectPic(&sPokemonLogoShineSpriteSheet[0]); + LoadPalette(gTitleScreenEmeraldVersionPal, 0x100, 0x20); + LoadSpritePalette(&sSpritePalette_PressStart[0]); + gMain.state = 2; + break; + case 2: + { + u8 taskId = CreateTask(Task_TitleScreenPhase1, 0); + + gTasks[taskId].tCounter = 256; + gTasks[taskId].tSkipToNext = FALSE; + gTasks[taskId].data[2] = -16; + gTasks[taskId].data[3] = -32; + gMain.state = 3; + break; + } + case 3: + BeginNormalPaletteFade(-1, 1, 0x10, 0, 0xFFFF); + SetVBlankCallback(VBlankCB); + gMain.state = 4; + break; + case 4: + sub_816F2A8(0x78, 0x50, 0x100, 0); + SetGpuReg(REG_OFFSET_BG2X_L, -29 * 256); + SetGpuReg(REG_OFFSET_BG2X_H, -1); + SetGpuReg(REG_OFFSET_BG2Y_L, -32 * 256); + SetGpuReg(REG_OFFSET_BG2Y_H, -1); + SetGpuReg(REG_OFFSET_WIN0H, 0); + SetGpuReg(REG_OFFSET_WIN0V, 0); + SetGpuReg(REG_OFFSET_WIN1H, 0); + SetGpuReg(REG_OFFSET_WIN1V, 0); + SetGpuReg(REG_OFFSET_WININ, 0x1F1F); + SetGpuReg(REG_OFFSET_WINOUT, 0x3F1F); + SetGpuReg(REG_OFFSET_BLDCNT, 0x84); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + SetGpuReg(REG_OFFSET_BLDY, 0xC); + SetGpuReg(REG_OFFSET_BG0CNT, BGCNT_PRIORITY(3) | BGCNT_CHARBASE(2) | BGCNT_SCREENBASE(26) | BGCNT_16COLOR | BGCNT_TXT256x256); + SetGpuReg(REG_OFFSET_BG1CNT, BGCNT_PRIORITY(2) | BGCNT_CHARBASE(3) | BGCNT_SCREENBASE(27) | BGCNT_16COLOR | BGCNT_TXT256x256); + SetGpuReg(REG_OFFSET_BG2CNT, BGCNT_PRIORITY(1) | BGCNT_CHARBASE(0) | BGCNT_SCREENBASE(9) | BGCNT_256COLOR | BGCNT_AFF256x256); + EnableInterrupts(INTR_FLAG_VBLANK); + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_1 + | DISPCNT_OBJ_1D_MAP + | DISPCNT_BG2_ON + | DISPCNT_OBJ_ON + | DISPCNT_WIN0_ON + | DISPCNT_OBJWIN_ON); + m4aSongNumStart(0x19D); + gMain.state = 5; + break; + case 5: + if (!UpdatePaletteFade()) + { + StartPokemonLogoShine(0); + ScanlineEffect_InitWave(0, DISPLAY_HEIGHT, 4, 4, 0, SCANLINE_EFFECT_REG_BG1HOFS, TRUE); + SetMainCallback2(MainCB2); + } + break; + } +} + +static void MainCB2(void) +{ + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); +} + +// Shine the Pokemon logo two more times, and fade in the version banner +static void Task_TitleScreenPhase1(u8 taskId) +{ + // Skip to next phase when A, B, Start, or Select is pressed + if ((gMain.newKeys & A_B_START_SELECT) || gTasks[taskId].data[1] != 0) + { + gTasks[taskId].tSkipToNext = TRUE; + gTasks[taskId].tCounter = 0; + } + + if (gTasks[taskId].tCounter != 0) + { + u16 frameNum = gTasks[taskId].tCounter; + if (frameNum == 176) + StartPokemonLogoShine(1); + else if (frameNum == 64) + StartPokemonLogoShine(2); + + gTasks[taskId].tCounter--; + } + else + { + u8 spriteId; + + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_1 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG2_ON | DISPCNT_OBJ_ON); + SetGpuReg(REG_OFFSET_WININ, 0); + SetGpuReg(REG_OFFSET_WINOUT, 0); + SetGpuReg(REG_OFFSET_BLDCNT, 0x3F50); + SetGpuReg(REG_OFFSET_BLDALPHA, 0x10); + SetGpuReg(REG_OFFSET_BLDY, 0); + + // Create left side of version banner + spriteId = CreateSprite(&sVersionBannerLeftSpriteTemplate, VERSION_BANNER_LEFT_X, VERSION_BANNER_Y, 0); + gSprites[spriteId].data[0] = 64; + gSprites[spriteId].data[1] = taskId; + + // Create right side of version banner + spriteId = CreateSprite(&sVersionBannerRightSpriteTemplate, VERSION_BANNER_RIGHT_X, VERSION_BANNER_Y, 0); + gSprites[spriteId].data[1] = taskId; + + gTasks[taskId].tCounter = 144; + gTasks[taskId].func = Task_TitleScreenPhase2; + } +} + +// Create "Press Start" and copyright banners, and slide Pokemon logo up +static void Task_TitleScreenPhase2(u8 taskId) +{ + u32 yPos; + + // Skip to next phase when A, B, Start, or Select is pressed + if ((gMain.newKeys & A_B_START_SELECT) || gTasks[taskId].tSkipToNext) + { + gTasks[taskId].tSkipToNext = TRUE; + gTasks[taskId].tCounter = 0; + } + + if (gTasks[taskId].tCounter != 0) + { + gTasks[taskId].tCounter--; + } + else + { + gTasks[taskId].tSkipToNext = TRUE; + SetGpuReg(REG_OFFSET_BLDCNT, 0x2142); + SetGpuReg(REG_OFFSET_BLDALPHA, 0xF06); + SetGpuReg(REG_OFFSET_BLDY, 0); + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_1 + | DISPCNT_OBJ_1D_MAP + | DISPCNT_BG0_ON + | DISPCNT_BG1_ON + | DISPCNT_BG2_ON + | DISPCNT_OBJ_ON); + CreatePressStartBanner(START_BANNER_X, 108); + CreateCopyrightBanner(START_BANNER_X, 148); + gTasks[taskId].data[4] = 0; + gTasks[taskId].func = Task_TitleScreenPhase3; + } + + if (!(gTasks[taskId].tCounter & 3) && gTasks[taskId].data[2] != 0) + gTasks[taskId].data[2]++; + if (!(gTasks[taskId].tCounter & 1) && gTasks[taskId].data[3] != 0) + gTasks[taskId].data[3]++; + + // Slide Pokemon logo up + yPos = gTasks[taskId].data[3] * 256; + SetGpuReg(REG_OFFSET_BG2Y_L, yPos); + SetGpuReg(REG_OFFSET_BG2Y_H, yPos / 0x10000); + + gTasks[taskId].data[5] = 15; + gTasks[taskId].data[6] = 6; +} + +// Show Rayquaza silhouette and process main title screen input +static void Task_TitleScreenPhase3(u8 taskId) +{ + if ((gMain.newKeys & A_BUTTON) || (gMain.newKeys & START_BUTTON)) + { + FadeOutBGM(4); + BeginNormalPaletteFade(-1, 0, 0, 0x10, 0xFFFF); + SetMainCallback2(CB2_GoToMainMenu); + } + else if ((gMain.heldKeys & CLEAR_SAVE_BUTTON_COMBO) == CLEAR_SAVE_BUTTON_COMBO) + { + SetMainCallback2(CB2_GoToClearSaveDataScreen); + } + else if ((gMain.heldKeys & RESET_RTC_BUTTON_COMBO) == RESET_RTC_BUTTON_COMBO + && CanResetRTC() == TRUE) + { + FadeOutBGM(4); + BeginNormalPaletteFade(-1, 0, 0, 0x10, 0); + SetMainCallback2(CB2_GoToResetRtcScreen); + } + else if ((gMain.heldKeys & BERRY_UPDATE_BUTTON_COMBO) == BERRY_UPDATE_BUTTON_COMBO) + { + FadeOutBGM(4); + BeginNormalPaletteFade(-1, 0, 0, 0x10, 0); + SetMainCallback2(CB2_GoToBerryFixScreen); + } + else + { + SetGpuReg(REG_OFFSET_BG2Y_L, 0); + SetGpuReg(REG_OFFSET_BG2Y_H, 0); + gTasks[taskId].tCounter++; + if (gTasks[taskId].tCounter & 1) + { + gTasks[taskId].data[4]++; + gBattle_BG1_Y = gTasks[taskId].data[4] / 2; + gBattle_BG1_X = 0; + } + UpdateLegendaryMarkingColor(gTasks[taskId].tCounter); + if ((gMPlayInfo_BGM.status & 0xFFFF) == 0) + { + BeginNormalPaletteFade(-1, 0, 0, 0x10, 0xFFFF); + SetMainCallback2(CB2_GoToCopyrightScreen); + } + } +} + +static void CB2_GoToMainMenu(void) +{ + if (!UpdatePaletteFade()) + SetMainCallback2(CB2_InitMainMenu); +} + +static void CB2_GoToCopyrightScreen(void) +{ + if (!UpdatePaletteFade()) + SetMainCallback2(CB2_InitCopyrightScreenAfterTitleScreen); +} + +static void CB2_GoToClearSaveDataScreen(void) +{ + if (!UpdatePaletteFade()) + SetMainCallback2(CB2_InitClearSaveDataScreen); +} + +static void CB2_GoToResetRtcScreen(void) +{ + if (!UpdatePaletteFade()) + SetMainCallback2(CB2_InitResetRtcScreen); +} + +static void CB2_GoToBerryFixScreen(void) +{ + if (!UpdatePaletteFade()) + { + m4aMPlayAllStop(); + SetMainCallback2(CB2_InitBerryFixProgram); + } +} + +static void UpdateLegendaryMarkingColor(u8 frameNum) +{ + if ((frameNum % 4) == 0) // Change color every 4th frame + { + s32 intensity = Cos(frameNum, 128) + 128; + s32 r = 31 - ((intensity * 32 - intensity) / 256); + s32 g = 31 - (intensity * 22 / 256); + s32 b = 12; + + u16 color = RGB(r, g, b); + LoadPalette(&color, 0xEF, sizeof(color)); + } +} |