417 lines
11 KiB
C
417 lines
11 KiB
C
#include "global.h"
|
|
#include "bg.h"
|
|
#include "decompress.h"
|
|
#include "palette.h"
|
|
#include "sound.h"
|
|
#include "sprite.h"
|
|
#include "task.h"
|
|
#include "gpu_regs.h"
|
|
#include "trig.h"
|
|
#include "main.h"
|
|
#include "intro.h"
|
|
#include "m4a.h"
|
|
#include "expansion_intro.h"
|
|
#include "constants/rgb.h"
|
|
#include "constants/songs.h"
|
|
|
|
#if EXPANSION_INTRO == TRUE
|
|
|
|
#define TAG_DIZZY 20000
|
|
#define TAG_PORYGON 20001
|
|
|
|
#define PAL_TAG_DIZZY 20000
|
|
#define PAL_TAG_PORYGON 20001
|
|
|
|
#define DIZZY_POS_X 300
|
|
#define DIZZY_POS_Y 138
|
|
#define DIZZY_COLLISION_POS_X 172
|
|
#define PORY_POS_X -32
|
|
#define PORY_POS_Y 115
|
|
#define PORYGON_COLLISION_POS_X 140
|
|
#define PORYGON_WAIT_TIME 99
|
|
|
|
#define DIZZY_ANIM_SPEED 4
|
|
#define DIZZY_STARS_SPEED 12
|
|
|
|
enum
|
|
{
|
|
EXPANSION_INTRO_BG2,
|
|
EXPANSION_INTRO_BG3
|
|
};
|
|
|
|
enum
|
|
{
|
|
ANIM_PORY_IDLE,
|
|
ANIM_PORY_HIT,
|
|
ANIM_PORY_GO_UP
|
|
};
|
|
|
|
enum
|
|
{
|
|
ANIM_DIZZY_WALKING,
|
|
ANIM_DIZZY_DIZZY
|
|
};
|
|
|
|
static const u32 sBgTiles_PoweredBy[] = INCBIN_U32("graphics/expansion_intro/powered_by.4bpp.lz");
|
|
static const u32 sBgTiles_RhhCredits[] = INCBIN_U32("graphics/expansion_intro/rhh_credits.8bpp.lz");
|
|
static const u32 sBgMap_PoweredBy[] = INCBIN_U32("graphics/expansion_intro/powered_by.bin.lz");
|
|
static const u32 sBgMap_RhhCredits[] = INCBIN_U32("graphics/expansion_intro/rhh_credits.bin.lz");
|
|
static const u32 sBgPal_Credits[] = INCBIN_U32("graphics/expansion_intro/credits.gbapal.lz");
|
|
static const u32 sSpriteTiles_DizzyEgg[] = INCBIN_U32("graphics/expansion_intro/sprites/dizzy_egg.4bpp.lz");
|
|
static const u32 sSpriteTiles_Porygon[] = INCBIN_U32("graphics/expansion_intro/sprites/porygon.4bpp.lz");
|
|
static const u16 sSpritePal_DizzyEgg[] = INCBIN_U16("graphics/expansion_intro/sprites/dizzy_egg.gbapal");
|
|
static const u16 sSpritePal_Porygon[] = INCBIN_U16("graphics/expansion_intro/sprites/porygon.gbapal");
|
|
static const u16 sSpritePal_PorygonShiny[] = INCBIN_U16("graphics/expansion_intro/sprites/shiny.gbapal");
|
|
|
|
static void SpriteCallback_DizzyWalking(struct Sprite* sprite);
|
|
static void SpriteCallback_PorygonFlying(struct Sprite* sprite);
|
|
static void Task_ExpansionIntro_HandleBlend(u8 taskId);
|
|
static void VBlankCB_ExpansionIntro(void);
|
|
static void ExpansionIntro_InitBgs();
|
|
static void ExpansionIntro_StartBlend();
|
|
static void ExpansionIntro_LoadGraphics();
|
|
static void ExpansionIntro_CreateSprites();
|
|
|
|
static const union AnimCmd sAnimCmd_DizzyWalking[] =
|
|
{
|
|
ANIMCMD_FRAME(32, DIZZY_ANIM_SPEED),
|
|
ANIMCMD_FRAME(16, DIZZY_ANIM_SPEED),
|
|
ANIMCMD_FRAME(0, DIZZY_ANIM_SPEED),
|
|
ANIMCMD_FRAME(16, DIZZY_ANIM_SPEED),
|
|
ANIMCMD_FRAME(32, DIZZY_ANIM_SPEED),
|
|
ANIMCMD_FRAME(48, DIZZY_ANIM_SPEED),
|
|
ANIMCMD_FRAME(64, DIZZY_ANIM_SPEED),
|
|
ANIMCMD_FRAME(48, DIZZY_ANIM_SPEED),
|
|
ANIMCMD_JUMP(0),
|
|
};
|
|
|
|
static const union AnimCmd sAnimCmd_DizzyisDizzy[] =
|
|
{
|
|
ANIMCMD_FRAME(80, DIZZY_STARS_SPEED),
|
|
ANIMCMD_FRAME(96, DIZZY_STARS_SPEED),
|
|
ANIMCMD_FRAME(112, DIZZY_STARS_SPEED),
|
|
ANIMCMD_FRAME(96, DIZZY_STARS_SPEED),
|
|
ANIMCMD_JUMP(0),
|
|
};
|
|
|
|
static const union AnimCmd *const sAnimCmdTable_DizzyEgg[] =
|
|
{
|
|
[ANIM_DIZZY_WALKING] = sAnimCmd_DizzyWalking,
|
|
[ANIM_DIZZY_DIZZY] = sAnimCmd_DizzyisDizzy,
|
|
};
|
|
|
|
static const union AnimCmd sAnimCmd_PorygonIdle[] =
|
|
{
|
|
ANIMCMD_FRAME(0, 0),
|
|
ANIMCMD_END,
|
|
};
|
|
|
|
static const union AnimCmd sAnimCmd_PorygonHitted[] =
|
|
{
|
|
ANIMCMD_FRAME(64, 0),
|
|
ANIMCMD_END,
|
|
};
|
|
|
|
static const union AnimCmd sAnimCmd_PorygonGoUp[] =
|
|
{
|
|
ANIMCMD_FRAME(64, 20),
|
|
ANIMCMD_FRAME(128, 10),
|
|
ANIMCMD_END,
|
|
};
|
|
|
|
static const union AnimCmd *const sAnimCmdTable_Porygon[] =
|
|
{
|
|
[ANIM_PORY_IDLE] = sAnimCmd_PorygonIdle,
|
|
[ANIM_PORY_HIT] = sAnimCmd_PorygonHitted,
|
|
[ANIM_PORY_GO_UP] = sAnimCmd_PorygonGoUp,
|
|
};
|
|
|
|
static const union AffineAnimCmd sAffineAnimCmd_PorygonScale[] =
|
|
{
|
|
AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
|
|
AFFINEANIMCMD_END,
|
|
};
|
|
|
|
static const union AffineAnimCmd *const sAffineAnimCmdTable_Porygon[] =
|
|
{
|
|
sAffineAnimCmd_PorygonScale,
|
|
};
|
|
|
|
static const struct CompressedSpriteSheet sSpriteSheet_DizzyEgg =
|
|
{
|
|
.data = sSpriteTiles_DizzyEgg,
|
|
.size = 0x1000,
|
|
.tag = TAG_DIZZY,
|
|
};
|
|
|
|
static const struct CompressedSpriteSheet sSpriteSheet_Porygon =
|
|
{
|
|
.data = sSpriteTiles_Porygon,
|
|
.size = 0x2800,
|
|
.tag = PAL_TAG_PORYGON,
|
|
};
|
|
|
|
static const struct SpritePalette sSpritePalette_DizzyEgg =
|
|
{
|
|
.data = sSpritePal_DizzyEgg,
|
|
.tag = PAL_TAG_DIZZY,
|
|
};
|
|
|
|
static const struct SpritePalette sSpritePalette_Porygon =
|
|
{
|
|
.data = sSpritePal_Porygon,
|
|
.tag = PAL_TAG_PORYGON,
|
|
};
|
|
|
|
static const struct OamData sOamData_DizzyEgg =
|
|
{
|
|
.affineMode = ST_OAM_AFFINE_OFF,
|
|
.objMode = ST_OAM_OBJ_NORMAL,
|
|
.mosaic = 0,
|
|
.bpp = ST_OAM_4BPP,
|
|
.shape = SPRITE_SHAPE(32x32),
|
|
.size = SPRITE_SIZE(32x32),
|
|
.priority = 0,
|
|
};
|
|
|
|
static const struct OamData sOamData_Porygon =
|
|
{
|
|
.affineMode = ST_OAM_AFFINE_NORMAL,
|
|
.objMode = ST_OAM_OBJ_NORMAL,
|
|
.mosaic = 0,
|
|
.bpp = ST_OAM_4BPP,
|
|
.shape = SPRITE_SHAPE(64x64),
|
|
.size = SPRITE_SIZE(64x64),
|
|
.priority = 0,
|
|
};
|
|
|
|
static const struct SpriteTemplate sSpriteTemplate_DizzyEgg =
|
|
{
|
|
.tileTag = TAG_DIZZY,
|
|
.paletteTag = PAL_TAG_DIZZY,
|
|
.oam = &sOamData_DizzyEgg,
|
|
.anims = sAnimCmdTable_DizzyEgg,
|
|
.images = NULL,
|
|
.affineAnims = gDummySpriteAffineAnimTable,
|
|
.callback = SpriteCallback_DizzyWalking,
|
|
};
|
|
|
|
static const struct SpriteTemplate sSpriteTemplate_Porygon =
|
|
{
|
|
.tileTag = TAG_PORYGON,
|
|
.paletteTag = PAL_TAG_PORYGON,
|
|
.oam = &sOamData_Porygon,
|
|
.anims = sAnimCmdTable_Porygon,
|
|
.images = NULL,
|
|
.affineAnims = sAffineAnimCmdTable_Porygon,
|
|
.callback = SpriteCallback_PorygonFlying,
|
|
};
|
|
|
|
static const struct BgTemplate sBgTemplates_RhhCopyrightScreen[] =
|
|
{
|
|
[EXPANSION_INTRO_BG2] = {
|
|
.bg = 2,
|
|
.charBaseIndex = 1,
|
|
.mapBaseIndex = 20,
|
|
.screenSize = 2,
|
|
.paletteMode = 1
|
|
},
|
|
[EXPANSION_INTRO_BG3] = {
|
|
.bg = 3,
|
|
.mapBaseIndex = 22,
|
|
.screenSize = 2
|
|
},
|
|
};
|
|
|
|
void CB2_ExpansionIntro(void)
|
|
{
|
|
RunTasks();
|
|
AnimateSprites();
|
|
BuildOamBuffer();
|
|
UpdatePaletteFade();
|
|
}
|
|
|
|
#define tState gTasks[taskId].data[0]
|
|
#define tFrameCounter gTasks[taskId].data[1]
|
|
void Task_HandleExpansionIntro(u8 taskId)
|
|
{
|
|
switch (tState)
|
|
{
|
|
case 0:
|
|
SetVBlankCallback(VBlankCB_ExpansionIntro);
|
|
ExpansionIntro_InitBgs();
|
|
ExpansionIntro_LoadGraphics();
|
|
CpuFastFill16(RGB_BLACK, gPlttBufferFaded, 32);
|
|
ShowBg(3);
|
|
BeginNormalPaletteFade(1, 0, 16, 0, RGB_BLACK);
|
|
ExpansionIntro_StartBlend();
|
|
ExpansionIntro_CreateSprites();
|
|
tState++;
|
|
break;
|
|
case 1:
|
|
if (!gPaletteFade.active)
|
|
tState++;
|
|
break;
|
|
case 2:
|
|
if (tFrameCounter == 208)
|
|
{
|
|
tState++;
|
|
BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK);
|
|
}
|
|
else if (gMain.newKeys != 0)
|
|
{
|
|
CpuFill16(0, gPlttBufferFaded, sizeof(gPlttBufferFaded));
|
|
if (IsCryPlaying())
|
|
StopCry();
|
|
m4aSongNumStop(SE_BIKE_HOP);
|
|
m4aSongNumStop(SE_M_DOUBLE_SLAP);
|
|
tState++;
|
|
}
|
|
else
|
|
{
|
|
tFrameCounter++;
|
|
}
|
|
break;
|
|
case 3:
|
|
if (!gPaletteFade.active)
|
|
{
|
|
ResetSpriteData();
|
|
FreeAllSpritePalettes();
|
|
DestroyTask(taskId);
|
|
CreateTask(Task_Scene1_Load, 0);
|
|
SetMainCallback2(MainCB2_Intro);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
#undef tState
|
|
|
|
static void VBlankCB_ExpansionIntro(void)
|
|
{
|
|
LoadOam();
|
|
ProcessSpriteCopyRequests();
|
|
TransferPlttBuffer();
|
|
}
|
|
|
|
static void ExpansionIntro_InitBgs(void)
|
|
{
|
|
ResetBgsAndClearDma3BusyFlags(0);
|
|
InitBgsFromTemplates(0, sBgTemplates_RhhCopyrightScreen, ARRAY_COUNT(sBgTemplates_RhhCopyrightScreen));
|
|
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_1D_MAP | DISPCNT_OBJ_ON);
|
|
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG2 | BLDCNT_TGT2_BG3 | BLDCNT_EFFECT_DARKEN);
|
|
SetGpuReg(REG_OFFSET_BLDY, 0x1F);
|
|
HideBg(0);
|
|
HideBg(1);
|
|
HideBg(2);
|
|
HideBg(3);
|
|
}
|
|
|
|
static void ExpansionIntro_LoadGraphics(void)
|
|
{
|
|
LZ77UnCompVram(sBgTiles_PoweredBy, (void*) BG_CHAR_ADDR(sBgTemplates_RhhCopyrightScreen[EXPANSION_INTRO_BG3].charBaseIndex));
|
|
LZ77UnCompVram(sBgMap_PoweredBy, (u16*) BG_SCREEN_ADDR(sBgTemplates_RhhCopyrightScreen[EXPANSION_INTRO_BG3].mapBaseIndex));
|
|
LZ77UnCompVram(sBgTiles_RhhCredits, (void*) BG_CHAR_ADDR(sBgTemplates_RhhCopyrightScreen[EXPANSION_INTRO_BG2].charBaseIndex));
|
|
LZ77UnCompVram(sBgMap_RhhCredits, (u16*) BG_SCREEN_ADDR(sBgTemplates_RhhCopyrightScreen[EXPANSION_INTRO_BG2].mapBaseIndex));
|
|
LoadCompressedPalette(sBgPal_Credits, 0x00, 0x60);
|
|
|
|
LoadCompressedSpriteSheet(&sSpriteSheet_DizzyEgg);
|
|
LoadCompressedSpriteSheet(&sSpriteSheet_Porygon);
|
|
LoadSpritePalette(&sSpritePalette_DizzyEgg);
|
|
LoadSpritePalette(&sSpritePalette_Porygon);
|
|
}
|
|
|
|
static void ExpansionIntro_CreateSprites(void)
|
|
{
|
|
u32 dizzyId, poryId;
|
|
|
|
dizzyId = CreateSprite(&sSpriteTemplate_DizzyEgg, 0, DIZZY_POS_Y, 0);
|
|
gSprites[dizzyId].x2 = DIZZY_POS_X;
|
|
|
|
poryId = CreateSprite(&sSpriteTemplate_Porygon, 0, PORY_POS_Y, 0);
|
|
gSprites[poryId].x2 = PORY_POS_X;
|
|
}
|
|
|
|
static void ExpansionIntro_StartBlend(void)
|
|
{
|
|
ShowBg(2);
|
|
CreateTask(Task_ExpansionIntro_HandleBlend, 0);
|
|
}
|
|
|
|
static void Task_ExpansionIntro_HandleBlend(u8 taskId)
|
|
{
|
|
if (GetGpuReg(REG_OFFSET_BLDY) != 0)
|
|
{
|
|
SetGpuReg(REG_OFFSET_BLDY, GetGpuReg(REG_OFFSET_BLDY) - 1);
|
|
}
|
|
else
|
|
{
|
|
SetGpuReg(REG_OFFSET_BLDCNT, 0);
|
|
DestroyTask(taskId);
|
|
}
|
|
}
|
|
|
|
#define sTimer data[0]
|
|
static void SpriteCallback_DizzyWalking(struct Sprite* sprite)
|
|
{
|
|
sprite->x2--;
|
|
|
|
if (sprite->x2 <= DIZZY_COLLISION_POS_X)
|
|
{
|
|
StartSpriteAnim(sprite, ANIM_DIZZY_DIZZY);
|
|
sprite->callback = SpriteCallbackDummy;
|
|
}
|
|
|
|
if (sprite->sTimer % 16 == 0 && sprite->sTimer / 16 > 2)
|
|
PlaySE(SE_BIKE_HOP);
|
|
|
|
sprite->sTimer++;
|
|
}
|
|
|
|
|
|
static void SpriteCallback_PorygonHit(struct Sprite* sprite)
|
|
{
|
|
sprite->x2-=2;
|
|
sprite ->y2 = Sin2(180 + sprite->sTimer * 4) / 128;
|
|
|
|
if (sprite->sTimer >= 48)
|
|
{
|
|
StartSpriteAnim(sprite, ANIM_PORY_GO_UP);
|
|
sprite->callback = SpriteCallbackDummy;
|
|
}
|
|
|
|
if (sprite->sTimer % 8 == 0)
|
|
{
|
|
if (sprite->sTimer % 16 == 0)
|
|
LoadPalette(sSpritePal_PorygonShiny, 0x10 * (16 + sprite->oam.paletteNum), 0x20);
|
|
else
|
|
LoadPalette(sSpritePal_Porygon, 0x10 * (16 + sprite->oam.paletteNum), 0x20);
|
|
}
|
|
|
|
sprite->sTimer++;
|
|
}
|
|
|
|
static void SpriteCallback_PorygonFlying(struct Sprite* sprite)
|
|
{
|
|
if (sprite->sTimer >= PORYGON_WAIT_TIME)
|
|
{
|
|
sprite->x2 += 6;
|
|
|
|
if (sprite->sTimer % 32 >= 16)
|
|
sprite->y2--;
|
|
else
|
|
sprite->y2++;
|
|
|
|
if (sprite->x2 >= PORYGON_COLLISION_POS_X)
|
|
{
|
|
StartSpriteAnim(sprite, ANIM_PORY_HIT);
|
|
sprite->callback = SpriteCallback_PorygonHit;
|
|
sprite->sTimer = 0;
|
|
PlaySE(SE_M_DOUBLE_SLAP);
|
|
PlayCryInternal(SPECIES_PORYGON, 0, 120, 10, 0);
|
|
}
|
|
}
|
|
sprite->sTimer++;
|
|
}
|
|
#undef sTimer
|
|
|
|
#endif //EXPANSION_INTRO
|