817 lines
23 KiB
C
817 lines
23 KiB
C
|
#include "global.h"
|
||
|
#include "battle.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 "graphics.h"
|
||
|
#include "constants/rgb.h"
|
||
|
#include "constants/songs.h"
|
||
|
|
||
|
#define VERSION_BANNER_RIGHT_TILEOFFSET 64
|
||
|
#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)
|
||
|
|
||
|
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 u32 sTitleScreenRayquazaGfx[] = INCBIN_U32("graphics/title_screen/rayquaza.4bpp.lz");
|
||
|
static const u32 sTitleScreenRayquazaTilemap[] = INCBIN_U32("graphics/title_screen/rayquaza.bin.lz");
|
||
|
static const u32 sTitleScreenLogoShineGfx[] = INCBIN_U32("graphics/title_screen/logo_shine.4bpp.lz");
|
||
|
static const u32 sTitleScreenCloudsGfx[] = INCBIN_U32("graphics/title_screen/clouds.4bpp.lz");
|
||
|
|
||
|
|
||
|
|
||
|
// Used to blend "Emerald Version" as it passes over over the Pokémon banner.
|
||
|
// Also used by the intro to blend the Game Freak name/logo in and out as they appear and disappear
|
||
|
const u16 gTitleScreenAlphaBlend[64] =
|
||
|
{
|
||
|
BLDALPHA_BLEND(16, 0),
|
||
|
BLDALPHA_BLEND(16, 1),
|
||
|
BLDALPHA_BLEND(16, 2),
|
||
|
BLDALPHA_BLEND(16, 3),
|
||
|
BLDALPHA_BLEND(16, 4),
|
||
|
BLDALPHA_BLEND(16, 5),
|
||
|
BLDALPHA_BLEND(16, 6),
|
||
|
BLDALPHA_BLEND(16, 7),
|
||
|
BLDALPHA_BLEND(16, 8),
|
||
|
BLDALPHA_BLEND(16, 9),
|
||
|
BLDALPHA_BLEND(16, 10),
|
||
|
BLDALPHA_BLEND(16, 11),
|
||
|
BLDALPHA_BLEND(16, 12),
|
||
|
BLDALPHA_BLEND(16, 13),
|
||
|
BLDALPHA_BLEND(16, 14),
|
||
|
BLDALPHA_BLEND(16, 15),
|
||
|
BLDALPHA_BLEND(15, 16),
|
||
|
BLDALPHA_BLEND(14, 16),
|
||
|
BLDALPHA_BLEND(13, 16),
|
||
|
BLDALPHA_BLEND(12, 16),
|
||
|
BLDALPHA_BLEND(11, 16),
|
||
|
BLDALPHA_BLEND(10, 16),
|
||
|
BLDALPHA_BLEND(9, 16),
|
||
|
BLDALPHA_BLEND(8, 16),
|
||
|
BLDALPHA_BLEND(7, 16),
|
||
|
BLDALPHA_BLEND(6, 16),
|
||
|
BLDALPHA_BLEND(5, 16),
|
||
|
BLDALPHA_BLEND(4, 16),
|
||
|
BLDALPHA_BLEND(3, 16),
|
||
|
BLDALPHA_BLEND(2, 16),
|
||
|
BLDALPHA_BLEND(1, 16),
|
||
|
BLDALPHA_BLEND(0, 16),
|
||
|
[32 ... 63] = BLDALPHA_BLEND(0, 16)
|
||
|
};
|
||
|
|
||
|
static const struct OamData sVersionBannerLeftOamData =
|
||
|
{
|
||
|
.y = DISPLAY_HEIGHT,
|
||
|
.affineMode = ST_OAM_AFFINE_OFF,
|
||
|
.objMode = ST_OAM_OBJ_NORMAL,
|
||
|
.mosaic = 0,
|
||
|
.bpp = ST_OAM_8BPP,
|
||
|
.shape = SPRITE_SHAPE(64x32),
|
||
|
.x = 0,
|
||
|
.matrixNum = 0,
|
||
|
.size = SPRITE_SIZE(64x32),
|
||
|
.tileNum = 0,
|
||
|
.priority = 0,
|
||
|
.paletteNum = 0,
|
||
|
.affineParam = 0,
|
||
|
};
|
||
|
|
||
|
static const struct OamData sVersionBannerRightOamData =
|
||
|
{
|
||
|
.y = DISPLAY_HEIGHT,
|
||
|
.affineMode = ST_OAM_AFFINE_OFF,
|
||
|
.objMode = ST_OAM_OBJ_NORMAL,
|
||
|
.mosaic = 0,
|
||
|
.bpp = ST_OAM_8BPP,
|
||
|
.shape = SPRITE_SHAPE(64x32),
|
||
|
.x = 0,
|
||
|
.matrixNum = 0,
|
||
|
.size = SPRITE_SIZE(64x32),
|
||
|
.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[] =
|
||
|
{
|
||
|
{
|
||
|
.data = gTitleScreenEmeraldVersionGfx,
|
||
|
.size = 0x1000,
|
||
|
.tag = 1000
|
||
|
},
|
||
|
{},
|
||
|
};
|
||
|
|
||
|
static const struct OamData sOamData_CopyrightBanner =
|
||
|
{
|
||
|
.y = DISPLAY_HEIGHT,
|
||
|
.affineMode = ST_OAM_AFFINE_OFF,
|
||
|
.objMode = ST_OAM_OBJ_NORMAL,
|
||
|
.mosaic = 0,
|
||
|
.bpp = ST_OAM_4BPP,
|
||
|
.shape = SPRITE_SHAPE(32x8),
|
||
|
.x = 0,
|
||
|
.matrixNum = 0,
|
||
|
.size = SPRITE_SIZE(32x8),
|
||
|
.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[] =
|
||
|
{
|
||
|
{
|
||
|
.data = gTitleScreenPressStartGfx,
|
||
|
.size = 0x520,
|
||
|
.tag = 1001
|
||
|
},
|
||
|
{},
|
||
|
};
|
||
|
|
||
|
static const struct SpritePalette sSpritePalette_PressStart[] =
|
||
|
{
|
||
|
{
|
||
|
.data = gTitleScreenPressStartPal,
|
||
|
.tag = 1001
|
||
|
},
|
||
|
{},
|
||
|
};
|
||
|
|
||
|
static const struct OamData sPokemonLogoShineOamData =
|
||
|
{
|
||
|
.y = DISPLAY_HEIGHT,
|
||
|
.affineMode = ST_OAM_AFFINE_OFF,
|
||
|
.objMode = ST_OAM_OBJ_NORMAL,
|
||
|
.mosaic = 0,
|
||
|
.bpp = ST_OAM_4BPP,
|
||
|
.shape = SPRITE_SHAPE(64x64),
|
||
|
.x = 0,
|
||
|
.matrixNum = 0,
|
||
|
.size = SPRITE_SIZE(64x64),
|
||
|
.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[] =
|
||
|
{
|
||
|
{
|
||
|
.data = sTitleScreenLogoShineGfx,
|
||
|
.size = 0x800,
|
||
|
.tag = 1002
|
||
|
},
|
||
|
{},
|
||
|
};
|
||
|
|
||
|
// code
|
||
|
static void SpriteCB_VersionBannerLeft(struct Sprite *sprite)
|
||
|
{
|
||
|
if (gTasks[sprite->data[1]].data[1] != 0)
|
||
|
{
|
||
|
sprite->oam.objMode = ST_OAM_OBJ_NORMAL;
|
||
|
sprite->y = VERSION_BANNER_Y_GOAL;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (sprite->y != VERSION_BANNER_Y_GOAL)
|
||
|
sprite->y++;
|
||
|
if (sprite->data[0] != 0)
|
||
|
sprite->data[0]--;
|
||
|
SetGpuReg(REG_OFFSET_BLDALPHA, gTitleScreenAlphaBlend[sprite->data[0]]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void SpriteCB_VersionBannerRight(struct Sprite *sprite)
|
||
|
{
|
||
|
if (gTasks[sprite->data[1]].data[1] != 0)
|
||
|
{
|
||
|
sprite->oam.objMode = ST_OAM_OBJ_NORMAL;
|
||
|
sprite->y = VERSION_BANNER_Y_GOAL;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (sprite->y != VERSION_BANNER_Y_GOAL)
|
||
|
sprite->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] & 16)
|
||
|
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->x < DISPLAY_WIDTH + 32)
|
||
|
{
|
||
|
if (sprite->data[0]) // Flash background
|
||
|
{
|
||
|
u16 backgroundColor;
|
||
|
|
||
|
if (sprite->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->x == DISPLAY_WIDTH / 2 + 12
|
||
|
|| sprite->x == DISPLAY_WIDTH / 2 + 16
|
||
|
|| sprite->x == DISPLAY_WIDTH / 2 + 20
|
||
|
|| sprite->x == DISPLAY_WIDTH / 2 + 24)
|
||
|
gPlttBufferFaded[0] = RGB(24, 31, 12);
|
||
|
else
|
||
|
gPlttBufferFaded[0] = backgroundColor;
|
||
|
}
|
||
|
sprite->x += 4;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
gPlttBufferFaded[0] = RGB_BLACK;
|
||
|
DestroySprite(sprite);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void SpriteCB_PokemonLogoShine2(struct Sprite *sprite)
|
||
|
{
|
||
|
if (sprite->x < DISPLAY_WIDTH + 32)
|
||
|
sprite->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 = ST_OAM_OBJ_WINDOW;
|
||
|
gSprites[spriteId].data[0] = flashBg;
|
||
|
break;
|
||
|
case 1:
|
||
|
spriteId = CreateSprite(&sPokemonLogoShineSpriteTemplate, 0, 68, 0);
|
||
|
gSprites[spriteId].oam.objMode = ST_OAM_OBJ_WINDOW;
|
||
|
gSprites[spriteId].data[0] = flashBg;
|
||
|
gSprites[spriteId].invisible = TRUE;
|
||
|
|
||
|
spriteId = CreateSprite(&sPokemonLogoShineSpriteTemplate, 0, 68, 0);
|
||
|
gSprites[spriteId].callback = SpriteCB_PokemonLogoShine2;
|
||
|
gSprites[spriteId].oam.objMode = ST_OAM_OBJ_WINDOW;
|
||
|
|
||
|
spriteId = CreateSprite(&sPokemonLogoShineSpriteTemplate, -80, 68, 0);
|
||
|
gSprites[spriteId].callback = SpriteCB_PokemonLogoShine2;
|
||
|
gSprites[spriteId].oam.objMode = ST_OAM_OBJ_WINDOW;
|
||
|
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:
|
||
|
// bg2
|
||
|
LZ77UnCompVram(gTitleScreenPokemonLogoGfx, (void *)(BG_CHAR_ADDR(0)));
|
||
|
LZ77UnCompVram(gTitleScreenPokemonLogoTilemap, (void *)(BG_SCREEN_ADDR(9)));
|
||
|
LoadPalette(gTitleScreenBgPalettes, 0, 0x1E0);
|
||
|
// bg3
|
||
|
LZ77UnCompVram(sTitleScreenRayquazaGfx, (void *)(BG_CHAR_ADDR(2)));
|
||
|
LZ77UnCompVram(sTitleScreenRayquazaTilemap, (void *)(BG_SCREEN_ADDR(26)));
|
||
|
// bg1
|
||
|
LZ77UnCompVram(sTitleScreenCloudsGfx, (void *)(BG_CHAR_ADDR(3)));
|
||
|
LZ77UnCompVram(gTitleScreenCloudsTilemap, (void *)(BG_SCREEN_ADDR(27)));
|
||
|
ScanlineEffect_Stop();
|
||
|
ResetTasks();
|
||
|
ResetSpriteData();
|
||
|
FreeAllSpritePalettes();
|
||
|
gReservedSpritePaletteCount = 9;
|
||
|
LoadCompressedSpriteSheet(&sSpriteSheet_EmeraldVersion[0]);
|
||
|
LoadCompressedSpriteSheet(&sSpriteSheet_PressStart[0]);
|
||
|
LoadCompressedSpriteSheet(&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(PALETTES_ALL, 1, 0x10, 0, RGB_WHITEALPHA);
|
||
|
SetVBlankCallback(VBlankCB);
|
||
|
gMain.state = 4;
|
||
|
break;
|
||
|
case 4:
|
||
|
PanFadeAndZoomScreen(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, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ);
|
||
|
SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WINOBJ_ALL);
|
||
|
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG2 | BLDCNT_EFFECT_LIGHTEN);
|
||
|
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
|
||
|
SetGpuReg(REG_OFFSET_BLDY, 12);
|
||
|
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(MUS_TITLE);
|
||
|
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, BLDCNT_TGT1_OBJ | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL);
|
||
|
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16, 0));
|
||
|
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, BLDCNT_TGT1_BG1 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG0 | BLDCNT_TGT2_BD);
|
||
|
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(6, 15));
|
||
|
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 ((JOY_NEW(A_BUTTON)) || (JOY_NEW(START_BUTTON)))
|
||
|
{
|
||
|
FadeOutBGM(4);
|
||
|
BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 0x10, RGB_WHITEALPHA);
|
||
|
SetMainCallback2(CB2_GoToMainMenu);
|
||
|
}
|
||
|
else if (JOY_HELD(CLEAR_SAVE_BUTTON_COMBO) == CLEAR_SAVE_BUTTON_COMBO)
|
||
|
{
|
||
|
SetMainCallback2(CB2_GoToClearSaveDataScreen);
|
||
|
}
|
||
|
else if (JOY_HELD(RESET_RTC_BUTTON_COMBO) == RESET_RTC_BUTTON_COMBO)
|
||
|
{
|
||
|
FadeOutBGM(4);
|
||
|
BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 0x10, RGB_BLACK);
|
||
|
SetMainCallback2(CB2_GoToResetRtcScreen);
|
||
|
}
|
||
|
else if (JOY_HELD(BERRY_UPDATE_BUTTON_COMBO) == BERRY_UPDATE_BUTTON_COMBO)
|
||
|
{
|
||
|
FadeOutBGM(4);
|
||
|
BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 0x10, RGB_BLACK);
|
||
|
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(PALETTES_ALL, 0, 0, 0x10, RGB_WHITEALPHA);
|
||
|
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));
|
||
|
}
|
||
|
}
|