diff --git a/data/field_effect_scripts.s b/data/field_effect_scripts.s index 1c97da8fe4..49fcf798b6 100644 --- a/data/field_effect_scripts.s +++ b/data/field_effect_scripts.s @@ -50,7 +50,7 @@ gFieldEffectScriptPointers:: .4byte gFieldEffectScript_HotSpringsWater @ FLDEFF_HOT_SPRINGS_WATER .4byte gFieldEffectScript_UseWaterfall @ FLDEFF_USE_WATERFALL .4byte gFieldEffectScript_UseDive @ FLDEFF_USE_DIVE - .4byte gFieldEffectScript_Pokeball @ FLDEFF_POKEBALL + .4byte gFieldEffectScript_PokeballTrail @ FLDEFF_POKEBALL_TRAIL .4byte gFieldEffectScript_HeartIcon @ FLDEFF_HEART_ICON .4byte gFieldEffectScript_Nop47 @ FLDEFF_NOP_47 .4byte gFieldEffectScript_Nop48 @ FLDEFF_NOP_48 @@ -254,9 +254,9 @@ gFieldEffectScript_UseDive:: field_eff_callnative FldEff_UseDive field_eff_end -gFieldEffectScript_Pokeball:: +gFieldEffectScript_PokeballTrail:: field_eff_loadpal gSpritePalette_Pokeball - field_eff_callnative FldEff_Pokeball + field_eff_callnative FldEff_PokeballTrail field_eff_end gFieldEffectScript_HeartIcon:: diff --git a/graphics/battle_transitions/85BDB14.pal b/graphics/battle_transitions/unused.pal similarity index 100% rename from graphics/battle_transitions/85BDB14.pal rename to graphics/battle_transitions/unused.pal diff --git a/include/battle_transition.h b/include/battle_transition.h index e978e9094c..1e7339fa2f 100644 --- a/include/battle_transition.h +++ b/include/battle_transition.h @@ -4,7 +4,7 @@ void BattleTransition_StartOnField(u8 transitionId); void BattleTransition_Start(u8 transitionId); bool8 IsBattleTransitionDone(void); -bool8 FldEff_Pokeball(void); +bool8 FldEff_PokeballTrail(void); void Task_BattleTransition_Intro(u8 taskId); void GetBg0TilesDst(u16 **tilemap, u16 **tileset); @@ -25,13 +25,13 @@ enum { B_TRANSITION_SHUFFLE, B_TRANSITION_BIG_POKEBALL, B_TRANSITION_POKEBALLS_TRAIL, - B_TRANSITION_CLOCKWISE_BLACKFADE, + B_TRANSITION_CLOCKWISE_WIPE, B_TRANSITION_RIPPLE, B_TRANSITION_WAVE, B_TRANSITION_SLICE, - B_TRANSITION_WHITEFADE, + B_TRANSITION_WHITE_BARS_FADE, B_TRANSITION_GRID_SQUARES, - B_TRANSITION_SHARDS, + B_TRANSITION_ANGLED_WIPES, B_TRANSITION_SIDNEY, B_TRANSITION_PHOEBE, B_TRANSITION_GLACIA, @@ -46,8 +46,8 @@ enum { B_TRANSITION_GROUDON, B_TRANSITION_RAYQUAZA, B_TRANSITION_SHRED_SPLIT, - B_TRANSITION_BLACKHOLE1, - B_TRANSITION_BLACKHOLE2, + B_TRANSITION_BLACKHOLE, + B_TRANSITION_BLACKHOLE_PULSATE, B_TRANSITION_RECTANGULAR_SPIRAL, B_TRANSITION_FRONTIER_LOGO_WIGGLE, B_TRANSITION_FRONTIER_LOGO_WAVE, diff --git a/include/constants/field_effects.h b/include/constants/field_effects.h index e02e01efbf..a620409479 100644 --- a/include/constants/field_effects.h +++ b/include/constants/field_effects.h @@ -46,7 +46,7 @@ #define FLDEFF_HOT_SPRINGS_WATER 42 #define FLDEFF_USE_WATERFALL 43 #define FLDEFF_USE_DIVE 44 -#define FLDEFF_POKEBALL 45 +#define FLDEFF_POKEBALL_TRAIL 45 #define FLDEFF_HEART_ICON 46 #define FLDEFF_NOP_47 47 #define FLDEFF_NOP_48 48 @@ -113,7 +113,7 @@ #define FLDEFF_PAL_TAG_GENERAL_1 0x1005 #define FLDEFF_PAL_TAG_POKEBALL_GLOW 0x1007 #define FLDEFF_PAL_TAG_SECRET_POWER_PLANT 0x1008 -#define FLDEFF_PAL_TAG_POKEBALL 0x1009 +#define FLDEFF_PAL_TAG_POKEBALL_TRAIL 0x1009 #define FLDEFF_PAL_TAG_ASH 0x100D #define FLDEFF_PAL_TAG_SAND_PILLAR 0x100E #define FLDEFF_PAL_TAG_SMALL_SPARKLE 0x100F diff --git a/src/battle_setup.c b/src/battle_setup.c index 6a4afe7462..b9833d20ae 100644 --- a/src/battle_setup.c +++ b/src/battle_setup.c @@ -112,15 +112,15 @@ EWRAM_DATA static u8 sNoOfPossibleTrainerRetScripts = 0; // Otherwise, the second transition is used. static const u8 sBattleTransitionTable_Wild[][2] = { - [TRANSITION_TYPE_NORMAL] = {B_TRANSITION_SLICE, B_TRANSITION_WHITEFADE}, - [TRANSITION_TYPE_CAVE] = {B_TRANSITION_CLOCKWISE_BLACKFADE, B_TRANSITION_GRID_SQUARES}, - [TRANSITION_TYPE_FLASH] = {B_TRANSITION_BLUR, B_TRANSITION_GRID_SQUARES}, - [TRANSITION_TYPE_WATER] = {B_TRANSITION_WAVE, B_TRANSITION_RIPPLE}, + [TRANSITION_TYPE_NORMAL] = {B_TRANSITION_SLICE, B_TRANSITION_WHITE_BARS_FADE}, + [TRANSITION_TYPE_CAVE] = {B_TRANSITION_CLOCKWISE_WIPE, B_TRANSITION_GRID_SQUARES}, + [TRANSITION_TYPE_FLASH] = {B_TRANSITION_BLUR, B_TRANSITION_GRID_SQUARES}, + [TRANSITION_TYPE_WATER] = {B_TRANSITION_WAVE, B_TRANSITION_RIPPLE}, }; static const u8 sBattleTransitionTable_Trainer[][2] = { - [TRANSITION_TYPE_NORMAL] = {B_TRANSITION_POKEBALLS_TRAIL, B_TRANSITION_SHARDS}, + [TRANSITION_TYPE_NORMAL] = {B_TRANSITION_POKEBALLS_TRAIL, B_TRANSITION_ANGLED_WIPES}, [TRANSITION_TYPE_CAVE] = {B_TRANSITION_SHUFFLE, B_TRANSITION_BIG_POKEBALL}, [TRANSITION_TYPE_FLASH] = {B_TRANSITION_BLUR, B_TRANSITION_GRID_SQUARES}, [TRANSITION_TYPE_WATER] = {B_TRANSITION_SWIRL, B_TRANSITION_RIPPLE}, @@ -555,7 +555,7 @@ void StartGroudonKyogreBattle(void) gBattleTypeFlags = BATTLE_TYPE_LEGENDARY | BATTLE_TYPE_KYOGRE_GROUDON; if (gGameVersion == VERSION_RUBY) - CreateBattleStartTask(B_TRANSITION_SHARDS, MUS_VS_KYOGRE_GROUDON); // GROUDON + CreateBattleStartTask(B_TRANSITION_ANGLED_WIPES, MUS_VS_KYOGRE_GROUDON); // GROUDON else CreateBattleStartTask(B_TRANSITION_RIPPLE, MUS_VS_KYOGRE_GROUDON); // KYOGRE diff --git a/src/battle_transition.c b/src/battle_transition.c index 72edf92d5c..88194db272 100644 --- a/src/battle_transition.c +++ b/src/battle_transition.c @@ -29,10 +29,27 @@ #define B_TRANS_DMA_FLAGS (1 | ((DMA_SRC_INC | DMA_DEST_FIXED | DMA_REPEAT | DMA_16BIT | DMA_START_HBLANK | DMA_ENABLE) << 16)) -#define SET_TILEMAP_TILE(ptr, posY, posX, toStore) \ -{ \ - u32 index = (posY) * 32 + posX; \ - ptr[index] = toStore; \ +// Used by each transition task to determine which of its functions to call +#define tState data[0] + +// Below are data defines for InitBlackWipe and UpdateBlackWipe, for the TransitionData data array. +// These will be re-used by any transitions that use these functions. +#define tWipeStartX data[0] +#define tWipeStartY data[1] +#define tWipeCurrX data[2] +#define tWipeCurrY data[3] +#define tWipeEndX data[4] +#define tWipeEndY data[5] +#define tWipeXMove data[6] +#define tWipeYMove data[7] +#define tWipeXDist data[8] +#define tWipeYDist data[9] +#define tWipeTemp data[10] + +#define SET_TILE(ptr, posY, posX, tile) \ +{ \ + u32 index = (posY) * 32 + posX; \ + ptr[index] = tile | (0xF0 << 8); \ } struct TransitionData @@ -53,17 +70,17 @@ struct TransitionData s16 BG0HOFS_Upper; s16 BG0VOFS; // used but not set s16 unused3; - s16 field_20; + s16 counter; s16 unused4; s16 data[11]; }; -struct StructRectangularSpiral +struct RectangularSpiralLine { - u8 field_0; - s16 field_2; - u8 field_4; - s16 field_6; + u8 state; + s16 position; + u8 moveIdx; + s16 skipPosition; u8 field_8; }; @@ -83,13 +100,13 @@ static void Task_Swirl(u8 taskId); static void Task_Shuffle(u8 taskId); static void Task_BigPokeball(u8 taskId); static void Task_PokeballsTrail(u8 taskId); -static void Task_Clockwise_BlackFade(u8 taskId); +static void Task_ClockwiseWipe(u8 taskId); static void Task_Ripple(u8 taskId); static void Task_Wave(u8 taskId); static void Task_Slice(u8 taskId); -static void Task_WhiteFade(u8 taskId); +static void Task_WhiteBarsFade(u8 taskId); static void Task_GridSquares(u8 taskId); -static void Task_Shards(u8 taskId); +static void Task_AngledWipes(u8 taskId); static void Task_Sidney(u8 taskId); static void Task_Phoebe(u8 taskId); static void Task_Glacia(u8 taskId); @@ -104,8 +121,8 @@ static void Task_Kyogre(u8 taskId); static void Task_Groudon(u8 taskId); static void Task_Rayquaza(u8 taskId); static void Task_ShredSplit(u8 taskId); -static void Task_Blackhole1(u8 taskId); -static void Task_Blackhole2(u8 taskId); +static void Task_Blackhole(u8 taskId); +static void Task_BlackholePulsate(u8 taskId); static void Task_RectangularSpiral(u8 taskId); static void Task_FrontierLogoWiggle(u8 taskId); static void Task_FrontierLogoWave(u8 taskId); @@ -118,8 +135,8 @@ static void HBlankCB_Swirl(void); static void VBlankCB_Shuffle(void); static void HBlankCB_Shuffle(void); static void VBlankCB_PatternWeave(void); -static void VBlankCB1_BigPokeball(void); -static void VBlankCB_Clockwise_BlackFade(void); +static void VBlankCB_CircularMask(void); +static void VBlankCB_ClockwiseWipe(void); static void VBlankCB_Ripple(void); static void HBlankCB_Ripple(void); static void VBlankCB_FrontierLogoWave(void); @@ -127,10 +144,10 @@ static void HBlankCB_FrontierLogoWave(void); static void VBlankCB_Wave(void); static void VBlankCB_Slice(void); static void HBlankCB_Slice(void); -static void VBlankCB0_WhiteFade(void); -static void VBlankCB1_WhiteFade(void); -static void HBlankCB_WhiteFade(void); -static void VBlankCB_Shards(void); +static void VBlankCB_WhiteBarsFade(void); +static void VBlankCB_WhiteBarsFade_Blend(void); +static void HBlankCB_WhiteBarsFade(void); +static void VBlankCB_AngledWipes(void); static void VBlankCB_Rayquaza(void); static bool8 Blur_Init(struct Task *task); static bool8 Blur_Main(struct Task *task); @@ -151,60 +168,60 @@ static bool8 Regirock_SetGfx(struct Task *task); static bool8 WeatherTrio_BgFadeBlack(struct Task *task); static bool8 WeatherTrio_WaitFade(struct Task *task); static bool8 Kyogre_Init(struct Task *task); -static bool8 Kyogre_PalettePulsate(struct Task *task); +static bool8 Kyogre_PaletteFlash(struct Task *task); static bool8 Kyogre_PaletteBrighten(struct Task *task); static bool8 Groudon_Init(struct Task *task); -static bool8 Groudon_PalettePulsate(struct Task *task); +static bool8 Groudon_PaletteFlash(struct Task *task); static bool8 Groudon_PaletteBrighten(struct Task *task); static bool8 WeatherDuo_FadeOut(struct Task *task); static bool8 WeatherDuo_End(struct Task *task); static bool8 BigPokeball_Init(struct Task *task); static bool8 BigPokeball_SetGfx(struct Task *task); -static bool8 PatternWeave_1(struct Task *task); -static bool8 PatternWeave_2(struct Task *task); -static bool8 PatternWeave_3(struct Task *task); -static bool8 PatternWeave_End(struct Task *task); +static bool8 PatternWeave_Blend1(struct Task *task); +static bool8 PatternWeave_Blend2(struct Task *task); +static bool8 PatternWeave_FinishAppear(struct Task *task); +static bool8 PatternWeave_CircularMask(struct Task *task); static bool8 PokeballsTrail_Init(struct Task *task); static bool8 PokeballsTrail_Main(struct Task *task); static bool8 PokeballsTrail_End(struct Task *task); -static bool8 Clockwise_BlackFade_Init(struct Task *task); -static bool8 Clockwise_BlackFade_Func2(struct Task *task); -static bool8 Clockwise_BlackFade_Func3(struct Task *task); -static bool8 Clockwise_BlackFade_Func4(struct Task *task); -static bool8 Clockwise_BlackFade_Func5(struct Task *task); -static bool8 Clockwise_BlackFade_Func6(struct Task *task); -static bool8 Clockwise_BlackFade_End(struct Task *task); +static bool8 ClockwiseWipe_Init(struct Task *task); +static bool8 ClockwiseWipe_TopRight(struct Task *task); +static bool8 ClockwiseWipe_Right(struct Task *task); +static bool8 ClockwiseWipe_Bottom(struct Task *task); +static bool8 ClockwiseWipe_Left(struct Task *task); +static bool8 ClockwiseWipe_TopLeft(struct Task *task); +static bool8 ClockwiseWipe_End(struct Task *task); static bool8 Ripple_Init(struct Task *task); -static bool8 Ripple_Func2(struct Task *task); +static bool8 Ripple_Main(struct Task *task); static bool8 Wave_Init(struct Task *task); -static bool8 Wave_Func2(struct Task *task); +static bool8 Wave_Main(struct Task *task); static bool8 Wave_End(struct Task *task); static bool8 Slice_Init(struct Task *task); -static bool8 Slice_Func2(struct Task *task); +static bool8 Slice_Main(struct Task *task); static bool8 Slice_End(struct Task *task); -static bool8 WhiteFade_Init(struct Task *task); -static bool8 WhiteFade_Func2(struct Task *task); -static bool8 WhiteFade_Func3(struct Task *task); -static bool8 WhiteFade_Func4(struct Task *task); -static bool8 WhiteFade_End(struct Task *task); +static bool8 WhiteBarsFade_Init(struct Task *task); +static bool8 WhiteBarsFade_StartBars(struct Task *task); +static bool8 WhiteBarsFade_WaitBars(struct Task *task); +static bool8 WhiteBarsFade_BlendToBlack(struct Task *task); +static bool8 WhiteBarsFade_End(struct Task *task); static bool8 GridSquares_Init(struct Task *task); -static bool8 GridSquares_Func2(struct Task *task); +static bool8 GridSquares_Main(struct Task *task); static bool8 GridSquares_End(struct Task *task); -static bool8 Shards_Init(struct Task *task); -static bool8 Shards_Func2(struct Task *task); -static bool8 Shards_Func3(struct Task *task); -static bool8 Shards_Func4(struct Task *task); -static bool8 Shards_Func5(struct Task *task); +static bool8 AngledWipes_Init(struct Task *task); +static bool8 AngledWipes_SetWipeData(struct Task *task); +static bool8 AngledWipes_DoWipe(struct Task *task); +static bool8 AngledWipes_TryEnd(struct Task *task); +static bool8 AngledWipes_StartNext(struct Task *task); static bool8 ShredSplit_Init(struct Task *task); -static bool8 ShredSplit_Func2(struct Task *task); -static bool8 ShredSplit_Func3(struct Task *task); +static bool8 ShredSplit_Main(struct Task *task); +static bool8 ShredSplit_BrokenCheck(struct Task *task); static bool8 ShredSplit_End(struct Task *task); static bool8 Blackhole_Init(struct Task *task); -static bool8 Blackhole1_Func2(struct Task *task); -static bool8 Blackhole1_Func3(struct Task *task); -static bool8 Blackhole2_Func2(struct Task *task); +static bool8 Blackhole_Vibrate(struct Task *task); +static bool8 Blackhole_GrowEnd(struct Task *task); +static bool8 BlackholePulsate_Main(struct Task *task); static bool8 RectangularSpiral_Init(struct Task *task); -static bool8 RectangularSpiral_Func2(struct Task *task); +static bool8 RectangularSpiral_Main(struct Task *task); static bool8 RectangularSpiral_End(struct Task *task); static bool8 FrontierLogoWiggle_Init(struct Task *task); static bool8 FrontierLogoWiggle_SetGfx(struct Task *task); @@ -212,16 +229,16 @@ static bool8 FrontierLogoWave_Init(struct Task *task); static bool8 FrontierLogoWave_SetGfx(struct Task *task); static bool8 FrontierLogoWave_Func3(struct Task *task); static bool8 FrontierLogoWave_Func4(struct Task *task); -static bool8 Rayquaza_Func3(struct Task *task); -static bool8 Rayquaza_Func4(struct Task *task); -static bool8 Rayquaza_Func5(struct Task *task); -static bool8 Rayquaza_Func6(struct Task *task); -static bool8 Rayquaza_Func7(struct Task *task); -static bool8 Rayquaza_Func8(struct Task *task); -static bool8 Rayquaza_Func9(struct Task *task); +static bool8 Rayquaza_Init(struct Task *task); +static bool8 Rayquaza_SetGfx(struct Task *task); +static bool8 Rayquaza_PaletteFlash(struct Task *task); +static bool8 Rayquaza_FadeToBlack(struct Task *task); +static bool8 Rayquaza_WaitFade(struct Task *task); +static bool8 Rayquaza_SetBlack(struct Task *task); +static bool8 Rayquaza_TriRing(struct Task *task); static bool8 FrontierSquares_Init(struct Task *task); -static bool8 FrontierSquares_Func2(struct Task *task); -static bool8 FrontierSquares_Func3(struct Task *task); +static bool8 FrontierSquares_Draw(struct Task *task); +static bool8 FrontierSquares_Shrink(struct Task *task); static bool8 FrontierSquares_End(struct Task *task); static bool8 FrontierSquaresSpiral_Init(struct Task *task); static bool8 FrontierSquaresSpiral_Func2(struct Task *task); @@ -244,37 +261,37 @@ static bool8 Mugshot_FadeToBlack(struct Task *task); static bool8 Mugshot_End(struct Task *task); static void DoMugshotTransition(u8 taskId); static void Mugshots_CreateTrainerPics(struct Task *task); -static void VBlankCB0_Mugshots(void); -static void VBlankCB1_Mugshots(void); +static void VBlankCB_Mugshots(void); +static void VBlankCB_MugshotsFadeOut(void); static void HBlankCB_Mugshots(void); static void InitTransitionData(void); static void FadeScreenBlack(void); static void CreateIntroTask(s16 a0, s16 a1, s16 a2, s16 a3, s16 a4); -static void sub_814A014(u16 *a0, s16 a1, s16 a2, s16 a3); +static void SetCircularMask(u16 *a0, s16 a1, s16 a2, s16 a3); static void SetSinWave(s16 *array, s16 sinAdd, s16 index, s16 indexIncrementer, s16 amplitude, s16 arrSize); static void GetBg0TilemapDst(u16 **tileset); -static void sub_814A1AC(s16 *a0, s16 a1, s16 a2, s16 a3, s16 a4, s16 a5, s16 a6); -static bool8 sub_814A228(s16 *a0, bool8 a1, bool8 a2); -static void SetTrainerPicSlideTable(s16 spriteId, s16 arrId); +static void InitBlackWipe(s16 *a0, s16 a1, s16 a2, s16 a3, s16 a4, s16 a5, s16 a6); +static bool8 UpdateBlackWipe(s16 *a0, bool8 a1, bool8 a2); +static void SetTrainerPicSlideDirection(s16 spriteId, s16 arrId); static void IncrementTrainerPicState(s16 spriteId); static s16 IsTrainerPicSlideDone(s16 spriteId); -static bool8 Transition_Intro_1(struct Task *task); -static bool8 Transition_Intro_2(struct Task *task); +static bool8 TransitionIntro_FadeToGray(struct Task *task); +static bool8 TransitionIntro_FadeFromGray(struct Task *task); static bool8 IsIntroTaskDone(void); -static bool16 sub_8149048(const s16 * const *arg0, struct StructRectangularSpiral *arg1); -static void SpriteCB_FldEffPokeball(struct Sprite *sprite); +static bool16 UpdateRectangularSpiralLine(const s16 * const *arg0, struct RectangularSpiralLine *arg1); +static void SpriteCB_FldEffPokeballTrail(struct Sprite *sprite); static void SpriteCB_MugshotTrainerPic(struct Sprite *sprite); -static void sub_8149864(struct Sprite *sprite); -static bool8 MugshotTrainerPic_Nothing(struct Sprite *sprite); -static bool8 MugshotTrainerPic_SetSlideOffsets(struct Sprite *sprite); -static bool8 MugshotTrainerPic_Slide1(struct Sprite *sprite); -static bool8 MugshotTrainerPic_Slide2(struct Sprite *sprite); -static bool8 MugshotTrainerPic_Slide3(struct Sprite *sprite); +static void SpriteCB_WhiteBarFade(struct Sprite *sprite); +static bool8 MugshotTrainerPic_Pause(struct Sprite *sprite); +static bool8 MugshotTrainerPic_Init(struct Sprite *sprite); +static bool8 MugshotTrainerPic_Slide(struct Sprite *sprite); +static bool8 MugshotTrainerPic_SlideSlow(struct Sprite *sprite); +static bool8 MugshotTrainerPic_SlideOffscreen(struct Sprite *sprite); -static s16 sUnusedRectangularSpiralVar; +static s16 sDebug_RectangularSpiralData; static u8 sTestingTransitionId; static u8 sTestingTransitionState; -static struct StructRectangularSpiral sRectangularSpiralTransition[4]; +static struct RectangularSpiralLine sRectangularSpiralLines[4]; EWRAM_DATA static struct TransitionData *sTransitionData = NULL; @@ -297,7 +314,7 @@ static const u16 sRegirock_Palette[] = INCBIN_U16("graphics/battle_transitions/r static const u32 sRegice_Tilemap[] = INCBIN_U32("graphics/battle_transitions/regice.bin"); static const u32 sRegisteel_Tilemap[] = INCBIN_U32("graphics/battle_transitions/registeel.bin"); static const u32 sRegirock_Tilemap[] = INCBIN_U32("graphics/battle_transitions/regirock.bin"); -static const u16 gUnknown_085BDB14[] = INCBIN_U16("graphics/battle_transitions/85BDB14.gbapal"); +static const u16 sUnused_Palette[] = INCBIN_U16("graphics/battle_transitions/unused.gbapal"); static const u32 sKyogre_Tileset[] = INCBIN_U32("graphics/battle_transitions/kyogre.4bpp.lz"); static const u32 sKyogre_Tilemap[] = INCBIN_U32("graphics/battle_transitions/kyogre.bin.lz"); static const u32 sGroudon_Tileset[] = INCBIN_U32("graphics/battle_transitions/groudon.4bpp.lz"); @@ -334,13 +351,13 @@ static const TaskFunc sTasks_Main[B_TRANSITION_COUNT] = [B_TRANSITION_SHUFFLE] = Task_Shuffle, [B_TRANSITION_BIG_POKEBALL] = Task_BigPokeball, [B_TRANSITION_POKEBALLS_TRAIL] = Task_PokeballsTrail, - [B_TRANSITION_CLOCKWISE_BLACKFADE] = Task_Clockwise_BlackFade, + [B_TRANSITION_CLOCKWISE_WIPE] = Task_ClockwiseWipe, [B_TRANSITION_RIPPLE] = Task_Ripple, [B_TRANSITION_WAVE] = Task_Wave, [B_TRANSITION_SLICE] = Task_Slice, - [B_TRANSITION_WHITEFADE] = Task_WhiteFade, + [B_TRANSITION_WHITE_BARS_FADE] = Task_WhiteBarsFade, [B_TRANSITION_GRID_SQUARES] = Task_GridSquares, - [B_TRANSITION_SHARDS] = Task_Shards, + [B_TRANSITION_ANGLED_WIPES] = Task_AngledWipes, [B_TRANSITION_SIDNEY] = Task_Sidney, [B_TRANSITION_PHOEBE] = Task_Phoebe, [B_TRANSITION_GLACIA] = Task_Glacia, @@ -355,8 +372,8 @@ static const TaskFunc sTasks_Main[B_TRANSITION_COUNT] = [B_TRANSITION_GROUDON] = Task_Groudon, [B_TRANSITION_RAYQUAZA] = Task_Rayquaza, [B_TRANSITION_SHRED_SPLIT] = Task_ShredSplit, - [B_TRANSITION_BLACKHOLE1] = Task_Blackhole1, - [B_TRANSITION_BLACKHOLE2] = Task_Blackhole2, + [B_TRANSITION_BLACKHOLE] = Task_Blackhole, + [B_TRANSITION_BLACKHOLE_PULSATE] = Task_BlackholePulsate, [B_TRANSITION_RECTANGULAR_SPIRAL] = Task_RectangularSpiral, [B_TRANSITION_FRONTIER_LOGO_WIGGLE] = Task_FrontierLogoWiggle, [B_TRANSITION_FRONTIER_LOGO_WAVE] = Task_FrontierLogoWave, @@ -404,62 +421,62 @@ static const TransitionStateFunc sAqua_Funcs[] = { Aqua_Init, Aqua_SetGfx, - PatternWeave_1, - PatternWeave_2, - PatternWeave_3, + PatternWeave_Blend1, + PatternWeave_Blend2, + PatternWeave_FinishAppear, FramesCountdown, - PatternWeave_End + PatternWeave_CircularMask }; static const TransitionStateFunc sMagma_Funcs[] = { Magma_Init, Magma_SetGfx, - PatternWeave_1, - PatternWeave_2, - PatternWeave_3, + PatternWeave_Blend1, + PatternWeave_Blend2, + PatternWeave_FinishAppear, FramesCountdown, - PatternWeave_End + PatternWeave_CircularMask }; static const TransitionStateFunc sBigPokeball_Funcs[] = { BigPokeball_Init, BigPokeball_SetGfx, - PatternWeave_1, - PatternWeave_2, - PatternWeave_3, - PatternWeave_End + PatternWeave_Blend1, + PatternWeave_Blend2, + PatternWeave_FinishAppear, + PatternWeave_CircularMask }; static const TransitionStateFunc sRegice_Funcs[] = { Regi_Init, Regice_SetGfx, - PatternWeave_1, - PatternWeave_2, - PatternWeave_3, - PatternWeave_End + PatternWeave_Blend1, + PatternWeave_Blend2, + PatternWeave_FinishAppear, + PatternWeave_CircularMask }; static const TransitionStateFunc sRegisteel_Funcs[] = { Regi_Init, Registeel_SetGfx, - PatternWeave_1, - PatternWeave_2, - PatternWeave_3, - PatternWeave_End + PatternWeave_Blend1, + PatternWeave_Blend2, + PatternWeave_FinishAppear, + PatternWeave_CircularMask }; static const TransitionStateFunc sRegirock_Funcs[] = { Regi_Init, Regirock_SetGfx, - PatternWeave_1, - PatternWeave_2, - PatternWeave_3, - PatternWeave_End + PatternWeave_Blend1, + PatternWeave_Blend2, + PatternWeave_FinishAppear, + PatternWeave_CircularMask }; static const TransitionStateFunc sKyogre_Funcs[] = @@ -467,7 +484,7 @@ static const TransitionStateFunc sKyogre_Funcs[] = WeatherTrio_BgFadeBlack, WeatherTrio_WaitFade, Kyogre_Init, - Kyogre_PalettePulsate, + Kyogre_PaletteFlash, Kyogre_PaletteBrighten, FramesCountdown, WeatherDuo_FadeOut, @@ -481,31 +498,32 @@ static const TransitionStateFunc sPokeballsTrail_Funcs[] = PokeballsTrail_End }; -static const s16 sUnknown_085C8B88[2] = {-16, 256}; -static const s16 sUnknown_085C8B8C[5] = {0, 32, 64, 18, 48}; -static const s16 sUnknown_085C8B96[2] = {8, -8}; +#define NUM_POKEBALL_TRAILS 5 +static const s16 sPokeballsTrail_StartXCoords[2] = { -16, DISPLAY_WIDTH + 16 }; +static const s16 sPokeballsTrail_Delays[NUM_POKEBALL_TRAILS] = {0, 32, 64, 18, 48}; +static const s16 sPokeballsTrail_Speeds[2] = {8, -8}; -static const TransitionStateFunc sClockwise_BlackFade_Funcs[] = +static const TransitionStateFunc sClockwiseWipe_Funcs[] = { - Clockwise_BlackFade_Init, - Clockwise_BlackFade_Func2, - Clockwise_BlackFade_Func3, - Clockwise_BlackFade_Func4, - Clockwise_BlackFade_Func5, - Clockwise_BlackFade_Func6, - Clockwise_BlackFade_End + ClockwiseWipe_Init, + ClockwiseWipe_TopRight, + ClockwiseWipe_Right, + ClockwiseWipe_Bottom, + ClockwiseWipe_Left, + ClockwiseWipe_TopLeft, + ClockwiseWipe_End }; static const TransitionStateFunc sRipple_Funcs[] = { Ripple_Init, - Ripple_Func2 + Ripple_Main }; static const TransitionStateFunc sWave_Funcs[] = { Wave_Init, - Wave_Func2, + Wave_Main, Wave_End }; @@ -550,76 +568,87 @@ static const s16 sMugshotsOpponentCoords[MUGSHOTS_COUNT][2] = static const TransitionSpriteCallback sMugshotTrainerPicFuncs[] = { - MugshotTrainerPic_Nothing, - MugshotTrainerPic_SetSlideOffsets, - MugshotTrainerPic_Slide1, - MugshotTrainerPic_Slide2, - MugshotTrainerPic_Nothing, - MugshotTrainerPic_Slide3, - MugshotTrainerPic_Nothing + MugshotTrainerPic_Pause, + MugshotTrainerPic_Init, + MugshotTrainerPic_Slide, + MugshotTrainerPic_SlideSlow, + MugshotTrainerPic_Pause, + MugshotTrainerPic_SlideOffscreen, + MugshotTrainerPic_Pause }; -static const s16 sTrainerPicSlideOffsets1[2] = {12, -12}; -static const s16 sTrainerPicSlideOffsets2[2] = {-1, 1}; +// One element per slide direction. +// Sign of acceleration is opposite speed, so slide decelerates. +static const s16 sTrainerPicSlideSpeeds[2] = {12, -12}; +static const s16 sTrainerPicSlideAccels[2] = {-1, 1}; static const TransitionStateFunc sSlice_Funcs[] = { Slice_Init, - Slice_Func2, + Slice_Main, Slice_End }; static const TransitionStateFunc sShredSplit_Funcs[] = { ShredSplit_Init, - ShredSplit_Func2, - ShredSplit_Func3, + ShredSplit_Main, + ShredSplit_BrokenCheck, ShredSplit_End }; -static const u8 gUnknown_085C8C64[] = {39, 119}; -static const s16 gUnknown_085C8C66[] = {1, -1}; +static const u8 sShredSplit_SectionYCoords[] = {39, DISPLAY_HEIGHT - 41}; +static const s16 sShredSplit_SectionMoveDirs[] = {1, -1}; -static const TransitionStateFunc sBlackhole1_Funcs[] = +static const TransitionStateFunc sBlackhole_Funcs[] = { Blackhole_Init, - Blackhole1_Func2, - Blackhole1_Func3 + Blackhole_Vibrate, + Blackhole_GrowEnd }; -static const TransitionStateFunc sBlackhole2_Funcs[] = +static const TransitionStateFunc sBlackholePulsate_Funcs[] = { Blackhole_Init, - Blackhole2_Func2 + BlackholePulsate_Main }; -static const s16 gUnknown_085C8C80[] = {-6, 4}; +// Blackhole rapidly alternates adding these values to the radius, +// resulting in a vibrating shrink/grow effect. +static const s16 sBlackhole_Vibrations[] = {-6, 4}; static const TransitionStateFunc sRectangularSpiral_Funcs[] = { RectangularSpiral_Init, - RectangularSpiral_Func2, + RectangularSpiral_Main, RectangularSpiral_End }; -static const s16 gUnknown_085C8C90[] = {1, 27, 275, -1}; -static const s16 gUnknown_085C8C98[] = {2, 486, -1}; -static const s16 gUnknown_085C8C9E[] = {3, 262, -1}; -static const s16 gUnknown_085C8CA4[] = {4, 507, -2}; -static const s16 gUnknown_085C8CAA[] = {1, 213, -1}; -static const s16 gUnknown_085C8CB0[] = {2, 548, -2}; -static const s16 gUnknown_085C8CB6[] = {3, 196, -1}; -static const s16 gUnknown_085C8CBC[] = {4, 573, 309, -1}; -static const s16 gUnknown_085C8CC4[] = {1, 474, -1}; -static const s16 gUnknown_085C8CCA[] = {2, 295, 32, -1}; -static const s16 gUnknown_085C8CD2[] = {3, 58, -1}; -static const s16 gUnknown_085C8CD8[] = {4, 455, -1}; -static const s16 gUnknown_085C8CDE[] = {1, 540, -1}; -static const s16 gUnknown_085C8CE4[] = {2, 229, -1}; -static const s16 gUnknown_085C8CEA[] = {3, 244, 28, -1}; -static const s16 gUnknown_085C8CF2[] = {4, 517, -1}; +#define SPIRAL_END (-1) +#define SPIRAL_SKIP (-2) -static const s16 *const gUnknown_085C8CF8[] = +static const s16 gUnknown_085C8C90[] = {1, 27, 275, SPIRAL_END}; +static const s16 gUnknown_085C8C98[] = {2, 486, SPIRAL_END}; +static const s16 gUnknown_085C8C9E[] = {3, 262, SPIRAL_END}; +static const s16 gUnknown_085C8CA4[] = {4, 507, SPIRAL_SKIP}; + +static const s16 gUnknown_085C8CAA[] = {1, 213, SPIRAL_END}; +static const s16 gUnknown_085C8CB0[] = {2, 548, SPIRAL_SKIP}; +static const s16 gUnknown_085C8CB6[] = {3, 196, SPIRAL_END}; +static const s16 gUnknown_085C8CBC[] = {4, 573, 309, SPIRAL_END}; + +static const s16 gUnknown_085C8CC4[] = {1, 474, SPIRAL_END}; +static const s16 gUnknown_085C8CCA[] = {2, 295, 32, SPIRAL_END}; +static const s16 gUnknown_085C8CD2[] = {3, 58, SPIRAL_END}; +static const s16 gUnknown_085C8CD8[] = {4, 455, SPIRAL_END}; + +static const s16 gUnknown_085C8CDE[] = {1, 540, SPIRAL_END}; +static const s16 gUnknown_085C8CE4[] = {2, 229, SPIRAL_END}; +static const s16 gUnknown_085C8CEA[] = {3, 244, 28, SPIRAL_END}; +static const s16 gUnknown_085C8CF2[] = {4, 517, SPIRAL_END}; + +// Move data for spiral lines starting in the top left / bottom right +static const s16 *const sRectangularSpiral_MoveDataTable_MajorDiagonal[] = { gUnknown_085C8C90, gUnknown_085C8CA4, @@ -631,7 +660,8 @@ static const s16 *const gUnknown_085C8CF8[] = gUnknown_085C8CDE }; -static const s16 *const gUnknown_085C8D18[] = +// Move data for spiral lines starting in the top right / bottom left +static const s16 *const sRectangularSpiral_MoveDataTable_MinorDiagonal[] = { gUnknown_085C8CBC, gUnknown_085C8CB0, @@ -643,10 +673,10 @@ static const s16 *const gUnknown_085C8D18[] = gUnknown_085C8CD2 }; -static const s16 *const *const gUnknown_085C8D38[] = +static const s16 *const *const sRectangularSpiral_MoveDataTables[] = { - gUnknown_085C8CF8, - gUnknown_085C8D18 + sRectangularSpiral_MoveDataTable_MajorDiagonal, + sRectangularSpiral_MoveDataTable_MinorDiagonal }; static const TransitionStateFunc sGroudon_Funcs[] = @@ -654,7 +684,7 @@ static const TransitionStateFunc sGroudon_Funcs[] = WeatherTrio_BgFadeBlack, WeatherTrio_WaitFade, Groudon_Init, - Groudon_PalettePulsate, + Groudon_PaletteFlash, Groudon_PaletteBrighten, FramesCountdown, WeatherDuo_FadeOut, @@ -665,61 +695,65 @@ static const TransitionStateFunc sRayquaza_Funcs[] = { WeatherTrio_BgFadeBlack, WeatherTrio_WaitFade, - Rayquaza_Func3, - Rayquaza_Func4, - Rayquaza_Func5, - Rayquaza_Func6, - Rayquaza_Func7, - Rayquaza_Func8, - Rayquaza_Func9, - Blackhole1_Func2, - Blackhole1_Func3 + Rayquaza_Init, + Rayquaza_SetGfx, + Rayquaza_PaletteFlash, + Rayquaza_FadeToBlack, + Rayquaza_WaitFade, + Rayquaza_SetBlack, + Rayquaza_TriRing, + Blackhole_Vibrate, + Blackhole_GrowEnd }; -static const TransitionStateFunc sWhiteFade_Funcs[] = +static const TransitionStateFunc sWhiteBarsFade_Funcs[] = { - WhiteFade_Init, - WhiteFade_Func2, - WhiteFade_Func3, - WhiteFade_Func4, - WhiteFade_End + WhiteBarsFade_Init, + WhiteBarsFade_StartBars, + WhiteBarsFade_WaitBars, + WhiteBarsFade_BlendToBlack, + WhiteBarsFade_End }; -static const s16 sUnknown_085C8DA0[] = {0, 20, 15, 40, 10, 25, 35, 5}; +#define NUM_WHITE_BARS 8 +static const s16 sWhiteBarsFade_StartDelays[NUM_WHITE_BARS] = {0, 20, 15, 40, 10, 25, 35, 5}; static const TransitionStateFunc sGridSquares_Funcs[] = { GridSquares_Init, - GridSquares_Func2, + GridSquares_Main, GridSquares_End }; -static const TransitionStateFunc sShards_Funcs[] = +static const TransitionStateFunc sAngledWipes_Funcs[] = { - Shards_Init, - Shards_Func2, - Shards_Func3, - Shards_Func4, - Shards_Func5 + AngledWipes_Init, + AngledWipes_SetWipeData, + AngledWipes_DoWipe, + AngledWipes_TryEnd, + AngledWipes_StartNext }; -static const s16 sUnknown_085C8DD0[][5] = +#define NUM_ANGLED_WIPES 7 + +static const s16 sAngledWipes_MoveData[NUM_ANGLED_WIPES][5] = { - {56, 0, 0, 160, 0}, - {104, 160, 240, 88, 1}, - {240, 72, 56, 0, 1}, - {0, 32, 144, 160, 0}, - {144, 160, 184, 0, 1}, - {56, 0, 168, 160, 0}, - {168, 160, 48, 0, 1}, +// startX startY endX endY yDirection + {56, 0, 0, DISPLAY_HEIGHT, 0}, + {104, DISPLAY_HEIGHT, DISPLAY_WIDTH, 88, 1}, + {DISPLAY_WIDTH, 72, 56, 0, 1}, + {0, 32, 144, DISPLAY_HEIGHT, 0}, + {144, DISPLAY_HEIGHT, 184, 0, 1}, + {56, 0, 168, DISPLAY_HEIGHT, 0}, + {168, DISPLAY_HEIGHT, 48, 0, 1}, }; -static const s16 sUnknown_085C8E16[] = {8, 4, 2, 1, 1, 1, 0}; +static const s16 sAngledWipes_EndDelays[NUM_ANGLED_WIPES] = {8, 4, 2, 1, 1, 1, 0}; static const TransitionStateFunc sTransitionIntroFuncs[] = { - Transition_Intro_1, - Transition_Intro_2 + TransitionIntro_FadeToGray, + TransitionIntro_FadeFromGray }; static const struct SpriteFrameImage sSpriteImage_Pokeball[] = @@ -759,12 +793,12 @@ static const union AffineAnimCmd *const sSpriteAffineAnimTable_Pokeball[] = static const struct SpriteTemplate sSpriteTemplate_Pokeball = { .tileTag = TAG_NONE, - .paletteTag = FLDEFF_PAL_TAG_POKEBALL, + .paletteTag = FLDEFF_PAL_TAG_POKEBALL_TRAIL, .oam = &gObjectEventBaseOam_32x32, .anims = sSpriteAnimTable_Pokeball, .images = sSpriteImage_Pokeball, .affineAnims = sSpriteAffineAnimTable_Pokeball, - .callback = SpriteCB_FldEffPokeball + .callback = SpriteCB_FldEffPokeballTrail }; static const struct OamData sOam_UnusedBrendanLass = @@ -829,7 +863,7 @@ static const struct SpriteTemplate sSpriteTemplate_UnusedLass = static const u16 sFieldEffectPal_Pokeball[] = INCBIN_U16("graphics/field_effects/palettes/pokeball.gbapal"); -const struct SpritePalette gSpritePalette_Pokeball = {sFieldEffectPal_Pokeball, FLDEFF_PAL_TAG_POKEBALL}; +const struct SpritePalette gSpritePalette_Pokeball = {sFieldEffectPal_Pokeball, FLDEFF_PAL_TAG_POKEBALL_TRAIL}; static const u16 sMugshotPal_Sidney[] = INCBIN_U16("graphics/battle_transitions/sidney_bg.gbapal"); static const u16 sMugshotPal_Phoebe[] = INCBIN_U16("graphics/battle_transitions/phoebe_bg.gbapal"); @@ -864,10 +898,10 @@ static const TransitionStateFunc sFrontierLogoWiggle_Funcs[] = { FrontierLogoWiggle_Init, FrontierLogoWiggle_SetGfx, - PatternWeave_1, - PatternWeave_2, - PatternWeave_3, - PatternWeave_End + PatternWeave_Blend1, + PatternWeave_Blend2, + PatternWeave_FinishAppear, + PatternWeave_CircularMask }; static const TransitionStateFunc sFrontierLogoWave_Funcs[] = @@ -881,8 +915,8 @@ static const TransitionStateFunc sFrontierLogoWave_Funcs[] = static const TransitionStateFunc sFrontierSquares_Funcs[] = { FrontierSquares_Init, - FrontierSquares_Func2, - FrontierSquares_Func3, + FrontierSquares_Draw, + FrontierSquares_Shrink, FrontierSquares_End }; @@ -968,9 +1002,6 @@ void BattleTransition_Start(u8 transitionId) LaunchBattleTransitionTask(transitionId); } -// in all tasks data[0] is reserved for the state -#define tState data[0] - // main task that launches sub-tasks for phase1 and phase2 #define tTransitionId data[1] #define tTransitionDone data[15] @@ -1063,11 +1094,6 @@ static void Task_Intro(u8 taskId) } } -#define tFuncState data[7] -#define tOpponentSpriteId data[13] -#define tPlayerSpriteId data[14] -#define tMugshotId data[15] - //-------------------- // B_TRANSITION_BLUR //-------------------- @@ -1270,10 +1296,10 @@ static void HBlankCB_Shuffle(void) #define tBlendTarget2 data[2] #define tBlendDelay data[3] -// Data 1-3 change purpose for PatternWeave_End -#define tEndAmplitude data[1] -#define tEndAmplitudeDelta data[2] -#define tVBlankSet data[3] +// Data 1-3 change purpose for PatternWeave_CircularMask +#define tRadius data[1] +#define tRadiusDelta data[2] +#define tVBlankSet data[3] #define tSinIndex data[4] #define tAmplitude data[5] @@ -1407,7 +1433,7 @@ static bool8 BigPokeball_SetGfx(struct Task *task) for (i = 0; i < 20; i++) { for (j = 0; j < 30; j++, bigPokeballMap++) - SET_TILEMAP_TILE(tilemap, i, j, *bigPokeballMap | 0xF000); + SET_TILE(tilemap, i, j, *bigPokeballMap); } SetSinWave(gScanlineEffectRegBuffers[0], 0, task->tSinIndex, 132, task->tAmplitude, DISPLAY_HEIGHT); @@ -1494,13 +1520,13 @@ static bool8 Kyogre_Init(struct Task *task) return FALSE; } -static bool8 Kyogre_PalettePulsate(struct Task *task) +static bool8 Kyogre_PaletteFlash(struct Task *task) { if (task->tTimer % 3 == 0) { - u16 var = task->tTimer % 30; - var /= 3; - LoadPalette(sKyogre1_Palette + (var * 16), 0xF0, 0x20); + u16 offset = task->tTimer % 30; + offset /= 3; + LoadPalette(&sKyogre1_Palette[offset * 16], 0xF0, 0x20); } if (++task->tTimer > 58) { @@ -1515,8 +1541,8 @@ static bool8 Kyogre_PaletteBrighten(struct Task *task) { if (task->tTimer % 5 == 0) { - s16 var = task->tTimer / 5; - LoadPalette(sKyogre2_Palette + (var * 16), 0xF0, 0x20); + s16 offset = task->tTimer / 5; + LoadPalette(&sKyogre2_Palette[offset * 16], 0xF0, 0x20); } if (++task->tTimer > 68) { @@ -1551,7 +1577,7 @@ static bool8 WeatherDuo_End(struct Task *task) // The PatternWeave_ functions are used by several different transitions. // They create an effect where a pattern/image (such as the Magma emblem) is // formed by a shimmering weave effect. -static bool8 PatternWeave_1(struct Task *task) +static bool8 PatternWeave_Blend1(struct Task *task) { sTransitionData->VBlank_DMA = FALSE; if (task->tBlendDelay == 0 || --task->tBlendDelay == 0) @@ -1571,7 +1597,7 @@ static bool8 PatternWeave_1(struct Task *task) return FALSE; } -static bool8 PatternWeave_2(struct Task *task) +static bool8 PatternWeave_Blend2(struct Task *task) { sTransitionData->VBlank_DMA = FALSE; if (task->tBlendDelay == 0 || --task->tBlendDelay == 0) @@ -1591,7 +1617,7 @@ static bool8 PatternWeave_2(struct Task *task) return FALSE; } -static bool8 PatternWeave_3(struct Task *task) +static bool8 PatternWeave_FinishAppear(struct Task *task) { sTransitionData->VBlank_DMA = FALSE; task->tSinIndex += 8; @@ -1602,8 +1628,8 @@ static bool8 PatternWeave_3(struct Task *task) if (task->tAmplitude <= 0) { task->tState++; - task->tEndAmplitude = 160; - task->tEndAmplitudeDelta = 256; + task->tRadius = DISPLAY_HEIGHT; + task->tRadiusDelta = 1 << 8; task->tVBlankSet = FALSE; } @@ -1632,19 +1658,20 @@ static bool8 WeatherTrio_WaitFade(struct Task *task) return FALSE; } -static bool8 PatternWeave_End(struct Task *task) +// Do a shrinking circular mask to go to a black screen after the pattern appears. +static bool8 PatternWeave_CircularMask(struct Task *task) { sTransitionData->VBlank_DMA = FALSE; - if (task->tEndAmplitudeDelta < 1024) - task->tEndAmplitudeDelta += 128; - if (task->tEndAmplitude != 0) + if (task->tRadiusDelta < (4 << 8)) + task->tRadiusDelta += 128; // 256 is 1 unit of speed. Speed up every other frame (128 / 256) + if (task->tRadius != 0) { - task->tEndAmplitude -= task->tEndAmplitudeDelta >> 8; - if (task->tEndAmplitude < 0) - task->tEndAmplitude = 0; + task->tRadius -= task->tRadiusDelta >> 8; + if (task->tRadius < 0) + task->tRadius = 0; } - sub_814A014(gScanlineEffectRegBuffers[0], 120, 80, task->tEndAmplitude); - if (task->tEndAmplitude == 0) + SetCircularMask(gScanlineEffectRegBuffers[0], DISPLAY_WIDTH / 2, DISPLAY_HEIGHT / 2, task->tRadius); + if (task->tRadius == 0) { SetVBlankCallback(NULL); DmaStop(0); @@ -1656,16 +1683,14 @@ static bool8 PatternWeave_End(struct Task *task) if (!task->tVBlankSet) { task->tVBlankSet++; - SetVBlankCallback(VBlankCB1_BigPokeball); + SetVBlankCallback(VBlankCB_CircularMask); } - sTransitionData->VBlank_DMA++; } - return FALSE; } -static void Transition_BigPokeball_Vblank(void) +static void VBlankCB_SetWinAndBlend(void) { DmaStop(0); VBlankCB_BattleTransition(); @@ -1680,13 +1705,13 @@ static void Transition_BigPokeball_Vblank(void) static void VBlankCB_PatternWeave(void) { - Transition_BigPokeball_Vblank(); + VBlankCB_SetWinAndBlend(); DmaSet(0, gScanlineEffectRegBuffers[1], ®_BG0HOFS, B_TRANS_DMA_FLAGS); } -static void VBlankCB1_BigPokeball(void) +static void VBlankCB_CircularMask(void) { - Transition_BigPokeball_Vblank(); + VBlankCB_SetWinAndBlend(); DmaSet(0, gScanlineEffectRegBuffers[1], ®_WIN0H, B_TRANS_DMA_FLAGS); } @@ -1694,9 +1719,18 @@ static void VBlankCB1_BigPokeball(void) #undef tSinIndex #undef tBlendTarget1 #undef tBlendTarget2 -#undef tEndAmplitude +#undef tRadius +#undef tRadiusDelta #undef tVBlankSet +//------------------------------ +// B_TRANSITION_POKEBALLS_TRAIL +//------------------------------ + +#define sSide data[0] +#define sDelay data[1] +#define sPrevX data[2] + static void Task_PokeballsTrail(u8 taskId) { while (sPokeballsTrail_Funcs[gTasks[taskId].tState](&gTasks[taskId])); @@ -1718,20 +1752,22 @@ static bool8 PokeballsTrail_Init(struct Task *task) static bool8 PokeballsTrail_Main(struct Task *task) { s16 i; - s16 rand; - s16 xCoords[ARRAY_COUNT(sUnknown_085C8B88)]; - s16 arr1[ARRAY_COUNT(sUnknown_085C8B8C)]; + s16 side; + s16 startX[ARRAY_COUNT(sPokeballsTrail_StartXCoords)]; + s16 delays[ARRAY_COUNT(sPokeballsTrail_Delays)]; + memcpy(startX, sPokeballsTrail_StartXCoords, sizeof(sPokeballsTrail_StartXCoords)); + memcpy(delays, sPokeballsTrail_Delays, sizeof(sPokeballsTrail_Delays)); - memcpy(xCoords, sUnknown_085C8B88, sizeof(sUnknown_085C8B88)); - memcpy(arr1, sUnknown_085C8B8C, sizeof(sUnknown_085C8B8C)); - rand = Random() & 1; - for (i = 0; i <= 4; i++, rand ^= 1) + // Randomly pick which side the first ball should start on. + // The side is then flipped for each subsequent ball. + side = Random() & 1; + for (i = 0; i < NUM_POKEBALL_TRAILS; i++, side ^= 1) { - gFieldEffectArguments[0] = xCoords[rand]; // x - gFieldEffectArguments[1] = (i * 32) + 16; // y - gFieldEffectArguments[2] = rand; - gFieldEffectArguments[3] = arr1[i]; - FieldEffectStart(FLDEFF_POKEBALL); + gFieldEffectArguments[0] = startX[side]; // x + gFieldEffectArguments[1] = (i * 32) + 16; // y + gFieldEffectArguments[2] = side; + gFieldEffectArguments[3] = delays[i]; + FieldEffectStart(FLDEFF_POKEBALL_TRAIL); } task->tState++; @@ -1740,7 +1776,7 @@ static bool8 PokeballsTrail_Main(struct Task *task) static bool8 PokeballsTrail_End(struct Task *task) { - if (!FieldEffectActiveListContains(FLDEFF_POKEBALL)) + if (!FieldEffectActiveListContains(FLDEFF_POKEBALL_TRAIL)) { FadeScreenBlack(); DestroyTask(FindTaskIdByFunc(Task_PokeballsTrail)); @@ -1748,70 +1784,72 @@ static bool8 PokeballsTrail_End(struct Task *task) return FALSE; } -#define sData0 data[0] -#define sData1 data[1] -#define sData2 data[2] - -bool8 FldEff_Pokeball(void) +bool8 FldEff_PokeballTrail(void) { u8 spriteId = CreateSpriteAtEnd(&sSpriteTemplate_Pokeball, gFieldEffectArguments[0], gFieldEffectArguments[1], 0); gSprites[spriteId].oam.priority = 0; gSprites[spriteId].oam.affineMode = ST_OAM_AFFINE_NORMAL; - gSprites[spriteId].sData0 = gFieldEffectArguments[2]; - gSprites[spriteId].sData1 = gFieldEffectArguments[3]; - gSprites[spriteId].sData2 = -1; + gSprites[spriteId].sSide = gFieldEffectArguments[2]; + gSprites[spriteId].sDelay = gFieldEffectArguments[3]; + gSprites[spriteId].sPrevX = -1; InitSpriteAffineAnim(&gSprites[spriteId]); StartSpriteAffineAnim(&gSprites[spriteId], gFieldEffectArguments[2]); return FALSE; } -static void SpriteCB_FldEffPokeball(struct Sprite *sprite) +static void SpriteCB_FldEffPokeballTrail(struct Sprite *sprite) { - s16 arr0[ARRAY_COUNT(sUnknown_085C8B96)]; + s16 speeds[ARRAY_COUNT(sPokeballsTrail_Speeds)]; + memcpy(speeds, sPokeballsTrail_Speeds, sizeof(sPokeballsTrail_Speeds)); - memcpy(arr0, sUnknown_085C8B96, sizeof(sUnknown_085C8B96)); - if (sprite->sData1 != 0) + if (sprite->sDelay != 0) { - sprite->sData1--; + sprite->sDelay--; } else { if (sprite->x >= 0 && sprite->x <= DISPLAY_WIDTH) { + // Set Pokéball position s16 posX = sprite->x >> 3; s16 posY = sprite->y >> 3; - if (posX != sprite->sData2) + // If Pokéball moved forward clear trail behind it + if (posX != sprite->sPrevX) { u32 var; u16 *ptr; - sprite->sData2 = posX; - var = (((REG_BG0CNT >> 8) & 0x1F) << 11); - ptr = (u16 *)(VRAM + var); + sprite->sPrevX = posX; + var = ((REG_BG0CNT >> 8) & 0x1F) << 11; + ptr = (u16 *)(BG_VRAM + var); - SET_TILEMAP_TILE(ptr, posY - 2, posX, 0xF001); - SET_TILEMAP_TILE(ptr, posY - 1, posX, 0xF001); - SET_TILEMAP_TILE(ptr, posY - 0, posX, 0xF001); - SET_TILEMAP_TILE(ptr, posY + 1, posX, 0xF001); + SET_TILE(ptr, posY - 2, posX, 1); + SET_TILE(ptr, posY - 1, posX, 1); + SET_TILE(ptr, posY - 0, posX, 1); + SET_TILE(ptr, posY + 1, posX, 1); } } - sprite->x += arr0[sprite->sData0]; + sprite->x += speeds[sprite->sSide]; if (sprite->x < -15 || sprite->x > DISPLAY_WIDTH + 15) - FieldEffectStop(sprite, FLDEFF_POKEBALL); + FieldEffectStop(sprite, FLDEFF_POKEBALL_TRAIL); } } -#undef sData0 -#undef sData1 -#undef sData2 +#undef sSide +#undef sDelay +#undef sPrevX -static void Task_Clockwise_BlackFade(u8 taskId) +//----------------------------- +// B_TRANSITION_CLOCKWISE_WIPE +//----------------------------- + +static void Task_ClockwiseWipe(u8 taskId) { - while (sClockwise_BlackFade_Funcs[gTasks[taskId].tState](&gTasks[taskId])); + while (sClockwiseWipe_Funcs[gTasks[taskId].tState](&gTasks[taskId])); } -static bool8 Clockwise_BlackFade_Init(struct Task *task) +static bool8 ClockwiseWipe_Init(struct Task *task) { u16 i; @@ -1824,29 +1862,29 @@ static bool8 Clockwise_BlackFade_Init(struct Task *task) sTransitionData->WIN0V = DISPLAY_HEIGHT; for (i = 0; i < DISPLAY_HEIGHT; i++) - gScanlineEffectRegBuffers[1][i] = WIN_RANGE(DISPLAY_WIDTH + 3, DISPLAY_WIDTH + 4); + gScanlineEffectRegBuffers[1][i] = ((DISPLAY_WIDTH + 3) << 8) | (DISPLAY_WIDTH + 4); - SetVBlankCallback(VBlankCB_Clockwise_BlackFade); - sTransitionData->data[4] = 120; + SetVBlankCallback(VBlankCB_ClockwiseWipe); + sTransitionData->tWipeEndX = DISPLAY_WIDTH / 2; task->tState++; return TRUE; } -static bool8 Clockwise_BlackFade_Func2(struct Task *task) +static bool8 ClockwiseWipe_TopRight(struct Task *task) { sTransitionData->VBlank_DMA = FALSE; - sub_814A1AC(sTransitionData->data, 120, 80, sTransitionData->data[4], -1, 1, 1); + InitBlackWipe(sTransitionData->data, DISPLAY_WIDTH / 2, DISPLAY_HEIGHT / 2, sTransitionData->tWipeEndX, -1, 1, 1); do { - gScanlineEffectRegBuffers[0][sTransitionData->data[3]] = (sTransitionData->data[2] + 1) | 0x7800; - } while (!sub_814A228(sTransitionData->data, 1, 1)); + gScanlineEffectRegBuffers[0][sTransitionData->tWipeCurrY] = (sTransitionData->tWipeCurrX + 1) | ((DISPLAY_WIDTH / 2) << 8); + } while (!UpdateBlackWipe(sTransitionData->data, TRUE, TRUE)); - sTransitionData->data[4] += 16; - if (sTransitionData->data[4] >= DISPLAY_WIDTH) + sTransitionData->tWipeEndX += 16; + if (sTransitionData->tWipeEndX >= DISPLAY_WIDTH) { - sTransitionData->data[5] = 0; + sTransitionData->tWipeEndY = 0; task->tState++; } @@ -1854,56 +1892,56 @@ static bool8 Clockwise_BlackFade_Func2(struct Task *task) return FALSE; } -static bool8 Clockwise_BlackFade_Func3(struct Task *task) +static bool8 ClockwiseWipe_Right(struct Task *task) { - s16 r1, r3; - vu8 var = 0; + s16 start, end; + vu8 finished = FALSE; sTransitionData->VBlank_DMA = FALSE; - sub_814A1AC(sTransitionData->data, 120, 80, 240, sTransitionData->data[5], 1, 1); + InitBlackWipe(sTransitionData->data, DISPLAY_WIDTH / 2, DISPLAY_HEIGHT / 2, DISPLAY_WIDTH, sTransitionData->tWipeEndY, 1, 1); while (1) { - r1 = 120, r3 = sTransitionData->data[2] + 1; - if (sTransitionData->data[5] >= DISPLAY_HEIGHT / 2) - r1 = sTransitionData->data[2], r3 = DISPLAY_WIDTH; - gScanlineEffectRegBuffers[0][sTransitionData->data[3]] = (r3) | (r1 << 8); - if (var != 0) + start = DISPLAY_WIDTH / 2, end = sTransitionData->tWipeCurrX + 1; + if (sTransitionData->tWipeEndY >= DISPLAY_HEIGHT / 2) + start = sTransitionData->tWipeCurrX, end = DISPLAY_WIDTH; + gScanlineEffectRegBuffers[0][sTransitionData->tWipeCurrY] = end | (start << 8); + if (finished) break; - var = sub_814A228(sTransitionData->data, 1, 1); + finished = UpdateBlackWipe(sTransitionData->data, TRUE, TRUE); } - sTransitionData->data[5] += 8; - if (sTransitionData->data[5] >= DISPLAY_HEIGHT) + sTransitionData->tWipeEndY += 8; + if (sTransitionData->tWipeEndY >= DISPLAY_HEIGHT) { - sTransitionData->data[4] = DISPLAY_WIDTH; + sTransitionData->tWipeEndX = DISPLAY_WIDTH; task->tState++; } else { - while (sTransitionData->data[3] < sTransitionData->data[5]) - gScanlineEffectRegBuffers[0][++sTransitionData->data[3]] = (r3) | (r1 << 8); + while (sTransitionData->tWipeCurrY < sTransitionData->tWipeEndY) + gScanlineEffectRegBuffers[0][++sTransitionData->tWipeCurrY] = end | (start << 8); } sTransitionData->VBlank_DMA++; return FALSE; } -static bool8 Clockwise_BlackFade_Func4(struct Task *task) +static bool8 ClockwiseWipe_Bottom(struct Task *task) { sTransitionData->VBlank_DMA = FALSE; - sub_814A1AC(sTransitionData->data, 120, 80, sTransitionData->data[4], 160, 1, 1); + InitBlackWipe(sTransitionData->data, DISPLAY_WIDTH / 2, DISPLAY_HEIGHT / 2, sTransitionData->tWipeEndX, DISPLAY_HEIGHT, 1, 1); do { - gScanlineEffectRegBuffers[0][sTransitionData->data[3]] = (sTransitionData->data[2] << 8) | 0xF0; - } while (!sub_814A228(sTransitionData->data, 1, 1)); + gScanlineEffectRegBuffers[0][sTransitionData->tWipeCurrY] = (sTransitionData->tWipeCurrX << 8) | DISPLAY_WIDTH; + } while (!UpdateBlackWipe(sTransitionData->data, TRUE, TRUE)); - sTransitionData->data[4] -= 16; - if (sTransitionData->data[4] <= 0) + sTransitionData->tWipeEndX -= 16; + if (sTransitionData->tWipeEndX <= 0) { - sTransitionData->data[5] = DISPLAY_HEIGHT; + sTransitionData->tWipeEndY = DISPLAY_HEIGHT; task->tState++; } @@ -1911,79 +1949,75 @@ static bool8 Clockwise_BlackFade_Func4(struct Task *task) return FALSE; } -static bool8 Clockwise_BlackFade_Func5(struct Task *task) +static bool8 ClockwiseWipe_Left(struct Task *task) { - s16 r1, r2, var4; - vu8 var = 0; + s16 end, start, temp; + vu8 finished = FALSE; sTransitionData->VBlank_DMA = FALSE; - sub_814A1AC(sTransitionData->data, 120, 80, 0, sTransitionData->data[5], 1, 1); + InitBlackWipe(sTransitionData->data, DISPLAY_WIDTH / 2, DISPLAY_HEIGHT / 2, 0, sTransitionData->tWipeEndY, 1, 1); while (1) { - r1 = (gScanlineEffectRegBuffers[0][sTransitionData->data[3]]) & 0xFF; - r2 = sTransitionData->data[2]; - if (sTransitionData->data[5] <= DISPLAY_HEIGHT / 2) - r2 = 120, r1 = sTransitionData->data[2]; - var4 = (r1) | (r2 << 8); - gScanlineEffectRegBuffers[0][sTransitionData->data[3]] = var4; - if (var != 0) + end = (gScanlineEffectRegBuffers[0][sTransitionData->tWipeCurrY]) & 0xFF; + start = sTransitionData->tWipeCurrX; + if (sTransitionData->tWipeEndY <= DISPLAY_HEIGHT / 2) + start = DISPLAY_WIDTH / 2, end = sTransitionData->tWipeCurrX; + temp = end | (start << 8); + gScanlineEffectRegBuffers[0][sTransitionData->tWipeCurrY] = temp; + if (finished) break; - var = sub_814A228(sTransitionData->data, 1, 1); + finished = UpdateBlackWipe(sTransitionData->data, TRUE, TRUE); } - sTransitionData->data[5] -= 8; - if (sTransitionData->data[5] <= 0) + sTransitionData->tWipeEndY -= 8; + if (sTransitionData->tWipeEndY <= 0) { - sTransitionData->data[4] = 0; + sTransitionData->tWipeEndX = 0; task->tState++; } else { - while (sTransitionData->data[3] > sTransitionData->data[5]) - { - gScanlineEffectRegBuffers[0][--sTransitionData->data[3]] = (r1) | (r2 << 8); - } + while (sTransitionData->tWipeCurrY > sTransitionData->tWipeEndY) + gScanlineEffectRegBuffers[0][--sTransitionData->tWipeCurrY] = end | (start << 8); } sTransitionData->VBlank_DMA++; return FALSE; } -static bool8 Clockwise_BlackFade_Func6(struct Task *task) +static bool8 ClockwiseWipe_TopLeft(struct Task *task) { sTransitionData->VBlank_DMA = FALSE; - sub_814A1AC(sTransitionData->data, 120, 80, sTransitionData->data[4], 0, 1, 1); + InitBlackWipe(sTransitionData->data, DISPLAY_WIDTH / 2, DISPLAY_HEIGHT / 2, sTransitionData->tWipeEndX, 0, 1, 1); do { - s16 r2, r3; + s16 start, end; + start = DISPLAY_WIDTH / 2, end = sTransitionData->tWipeCurrX; + if (sTransitionData->tWipeCurrX >= DISPLAY_WIDTH / 2) + start = 0, end = DISPLAY_WIDTH; + gScanlineEffectRegBuffers[0][sTransitionData->tWipeCurrY] = end | (start << 8); + } while (!UpdateBlackWipe(sTransitionData->data, TRUE, TRUE)); - r2 = 120, r3 = sTransitionData->data[2]; - if (sTransitionData->data[2] >= 120) - r2 = 0, r3 = DISPLAY_WIDTH; - gScanlineEffectRegBuffers[0][sTransitionData->data[3]] = (r3) | (r2 << 8); - - } while (!sub_814A228(sTransitionData->data, 1, 1)); - - sTransitionData->data[4] += 16; - if (sTransitionData->data[2] > 120) + sTransitionData->tWipeEndX += 16; + if (sTransitionData->tWipeCurrX > DISPLAY_WIDTH / 2) task->tState++; sTransitionData->VBlank_DMA++; return FALSE; } -static bool8 Clockwise_BlackFade_End(struct Task *task) +static bool8 ClockwiseWipe_End(struct Task *task) { DmaStop(0); FadeScreenBlack(); - DestroyTask(FindTaskIdByFunc(Task_Clockwise_BlackFade)); + DestroyTask(FindTaskIdByFunc(Task_ClockwiseWipe)); return FALSE; } -static void VBlankCB_Clockwise_BlackFade(void) +static void VBlankCB_ClockwiseWipe(void) { DmaStop(0); VBlankCB_BattleTransition(); @@ -1996,6 +2030,15 @@ static void VBlankCB_Clockwise_BlackFade(void) DmaSet(0, gScanlineEffectRegBuffers[1], ®_WIN0H, B_TRANS_DMA_FLAGS); } +//--------------------- +// B_TRANSITION_RIPPLE +//--------------------- + +#define tSinVal data[1] +#define tAmplitudeVal data[2] +#define tTimer data[3] +#define tFadeStarted data[4] + static void Task_Ripple(u8 taskId) { while (sRipple_Funcs[gTasks[taskId].tState](&gTasks[taskId])); @@ -2020,34 +2063,34 @@ static bool8 Ripple_Init(struct Task *task) return TRUE; } -static bool8 Ripple_Func2(struct Task *task) +static bool8 Ripple_Main(struct Task *task) { u8 i; - s16 r3; - u16 r4, r8; + s16 amplitude; + u16 sinVal, speed; sTransitionData->VBlank_DMA = FALSE; - r3 = task->data[2] >> 8; - r4 = task->data[1]; - r8 = 384; - task->data[1] += 0x400; - if (task->data[2] <= 0x1FFF) - task->data[2] += 0x180; + amplitude = task->tAmplitudeVal >> 8; + sinVal = task->tSinVal; + speed = 0x180; + task->tSinVal += 0x400; + if (task->tAmplitudeVal <= 0x1FFF) + task->tAmplitudeVal += 0x180; - for (i = 0; i < DISPLAY_HEIGHT; i++, r4 += r8) + for (i = 0; i < DISPLAY_HEIGHT; i++, sinVal += speed) { - s16 var = r4 >> 8; - gScanlineEffectRegBuffers[0][i] = sTransitionData->cameraY + Sin(var & 0xffff, r3); + s16 sinIndex = sinVal >> 8; + gScanlineEffectRegBuffers[0][i] = sTransitionData->cameraY + Sin(sinIndex & 0xffff, amplitude); } - if (++task->data[3] == 81) + if (++task->tTimer == 81) { - task->data[4]++; + task->tFadeStarted++; BeginNormalPaletteFade(PALETTES_ALL, -2, 0, 16, RGB_BLACK); } - if (task->data[4] != 0 && !gPaletteFade.active) + if (task->tFadeStarted && !gPaletteFade.active) DestroyTask(FindTaskIdByFunc(Task_Ripple)); sTransitionData->VBlank_DMA++; @@ -2069,7 +2112,18 @@ static void HBlankCB_Ripple(void) REG_BG3VOFS = var; } +#undef tSinVal +#undef tAmplitudeVal +#undef tTimer +#undef tFadeStarted + +//------------------- // B_TRANSITION_WAVE +//------------------- + +#define tX data[1] +#define tSinIndex data[2] + static void Task_Wave(u8 taskId) { while (sWave_Funcs[gTasks[taskId].tState](&gTasks[taskId])); @@ -2096,30 +2150,30 @@ static bool8 Wave_Init(struct Task *task) return TRUE; } -static bool8 Wave_Func2(struct Task *task) +static bool8 Wave_Main(struct Task *task) { - u8 i, r5; + u8 i, sinIndex; u16* toStore; - bool8 nextFunc; + bool8 finished; sTransitionData->VBlank_DMA = FALSE; toStore = gScanlineEffectRegBuffers[0]; - r5 = task->data[2]; - task->data[2] += 16; - task->data[1] += 8; + sinIndex = task->tSinIndex; + task->tSinIndex += 16; + task->tX += 8; - for (i = 0, nextFunc = TRUE; i < DISPLAY_HEIGHT; i++, r5 += 4, toStore++) + for (i = 0, finished = TRUE; i < DISPLAY_HEIGHT; i++, sinIndex += 4, toStore++) { - s16 value = task->data[1] + Sin(r5, 40); - if (value < 0) - value = 0; - if (value > DISPLAY_WIDTH) - value = DISPLAY_WIDTH; - *toStore = (value << 8) | (DISPLAY_WIDTH + 1); - if (value < DISPLAY_WIDTH) - nextFunc = FALSE; + s16 x = task->tX + Sin(sinIndex, 40); + if (x < 0) + x = 0; + if (x > DISPLAY_WIDTH) + x = DISPLAY_WIDTH; + *toStore = (x << 8) | (DISPLAY_WIDTH + 1); + if (x < DISPLAY_WIDTH) + finished = FALSE; } - if (nextFunc) + if (finished) task->tState++; sTransitionData->VBlank_DMA++; @@ -2146,6 +2200,33 @@ static void VBlankCB_Wave(void) DmaSet(0, gScanlineEffectRegBuffers[1], ®_WIN0H, B_TRANS_DMA_FLAGS); } +#undef tX +#undef tSinIndex + +//---------------------------------------------------------------- +// B_TRANSITION_SIDNEY, B_TRANSITION_PHOEBE, B_TRANSITION_GLACIA, +// B_TRANSITION_DRAKE, and B_TRANSITION_CHAMPION +// +// These are all the "mugshot" transitions, where a banner shows +// the trainer pic of the player and their opponent. +//---------------------------------------------------------------- + +#define tSinIndex data[1] +#define tTopBannerX data[2] +#define tBottomBannerX data[3] +#define tTimer data[3] // Re-used +#define tFadeSpread data[4] +#define tOpponentSpriteId data[13] +#define tPlayerSpriteId data[14] +#define tMugshotId data[15] + +// Sprite data for trainer sprites in mugshots +#define sState data[0] +#define sSlideSpeed data[1] +#define sSlideAccel data[2] +#define sDone data[6] +#define sSlideDir data[7] + static void Task_Sidney(u8 taskId) { gTasks[taskId].tMugshotId = MUGSHOT_SIDNEY; @@ -2189,17 +2270,17 @@ static bool8 Mugshot_Init(struct Task *task) ScanlineEffect_Clear(); Mugshots_CreateTrainerPics(task); - task->data[1] = 0; - task->data[2] = 1; - task->data[3] = DISPLAY_WIDTH - 1; + task->tSinIndex = 0; + task->tTopBannerX = 1; + task->tBottomBannerX = DISPLAY_WIDTH - 1; sTransitionData->WININ = WININ_WIN0_ALL; sTransitionData->WINOUT = WINOUT_WIN01_BG1 | WINOUT_WIN01_BG2 | WINOUT_WIN01_BG3 | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR; sTransitionData->WIN0V = DISPLAY_HEIGHT; for (i = 0; i < DISPLAY_HEIGHT; i++) - gScanlineEffectRegBuffers[1][i] = 0xF0F1; + gScanlineEffectRegBuffers[1][i] = (DISPLAY_WIDTH << 8) | (DISPLAY_WIDTH + 1); - SetVBlankCallback(VBlankCB0_Mugshots); + SetVBlankCallback(VBlankCB_Mugshots); task->tState++; return FALSE; @@ -2220,7 +2301,7 @@ static bool8 Mugshot_SetGfx(struct Task *task) for (i = 0; i < 20; i++) { for (j = 0; j < 32; j++, mugshotsMap++) - SET_TILEMAP_TILE(tilemap, i, j, *mugshotsMap | 0xF000); + SET_TILE(tilemap, i, j, *mugshotsMap); } EnableInterrupts(INTR_FLAG_HBLANK); @@ -2232,43 +2313,49 @@ static bool8 Mugshot_SetGfx(struct Task *task) static bool8 Mugshot_ShowBanner(struct Task *task) { - u8 i, r5; + u8 i, sinIndex; u16* toStore; - s16 value; + s16 x; s32 mergedValue; sTransitionData->VBlank_DMA = FALSE; toStore = gScanlineEffectRegBuffers[0]; - r5 = task->data[1]; - task->data[1] += 16; + sinIndex = task->tSinIndex; + task->tSinIndex += 16; - for (i = 0; i < DISPLAY_HEIGHT / 2; i++, toStore++, r5 += 16) + // Update top banner + for (i = 0; i < DISPLAY_HEIGHT / 2; i++, toStore++, sinIndex += 16) { - value = task->data[2] + Sin(r5, 16); - if (value < 0) - value = 1; - if (value > DISPLAY_WIDTH) - value = DISPLAY_WIDTH; - *toStore = value; - } - for (; i < DISPLAY_HEIGHT; i++, toStore++, r5 += 16) - { - value = task->data[3] - Sin(r5, 16); - if (value < 0) - value = 0; - if (value > DISPLAY_WIDTH - 1) - value = DISPLAY_WIDTH - 1; - *toStore = (value << 8) | (DISPLAY_WIDTH); + x = task->tTopBannerX + Sin(sinIndex, 16); + if (x < 0) + x = 1; + if (x > DISPLAY_WIDTH) + x = DISPLAY_WIDTH; + *toStore = x; } - task->data[2] += 8; - task->data[3] -= 8; - if (task->data[2] > DISPLAY_WIDTH) - task->data[2] = DISPLAY_WIDTH; - if (task->data[3] < 0) - task->data[3] = 0; - mergedValue = *(s32*)(&task->data[2]); + // Update bottom banner + for (; i < DISPLAY_HEIGHT; i++, toStore++, sinIndex += 16) + { + x = task->tBottomBannerX - Sin(sinIndex, 16); + if (x < 0) + x = 0; + if (x > DISPLAY_WIDTH - 1) + x = DISPLAY_WIDTH - 1; + *toStore = (x << 8) | DISPLAY_WIDTH; + } + + // Slide banners across screen + task->tTopBannerX += 8; + task->tBottomBannerX -= 8; + + if (task->tTopBannerX > DISPLAY_WIDTH) + task->tTopBannerX = DISPLAY_WIDTH; + if (task->tBottomBannerX < 0) + task->tBottomBannerX = 0; + + mergedValue = *(s32*)(&task->tTopBannerX); if (mergedValue == DISPLAY_WIDTH) task->tState++; @@ -2289,15 +2376,19 @@ static bool8 Mugshot_StartOpponentSlide(struct Task *task) *toStore = DISPLAY_WIDTH; task->tState++; - task->data[1] = 0; - task->data[2] = 0; - task->data[3] = 0; + + // Clear old data + task->tSinIndex = 0; + task->tTopBannerX = 0; + task->tBottomBannerX = 0; sTransitionData->BG0HOFS_Lower -= 8; sTransitionData->BG0HOFS_Upper += 8; - SetTrainerPicSlideTable(task->tOpponentSpriteId, 0); - SetTrainerPicSlideTable(task->tPlayerSpriteId, 1); + SetTrainerPicSlideDirection(task->tOpponentSpriteId, 0); + SetTrainerPicSlideDirection(task->tPlayerSpriteId, 1); + + // Start opponent slide IncrementTrainerPicState(task->tOpponentSpriteId); PlaySE(SE_MUGSHOT); @@ -2311,7 +2402,7 @@ static bool8 Mugshot_WaitStartPlayerSlide(struct Task *task) sTransitionData->BG0HOFS_Lower -= 8; sTransitionData->BG0HOFS_Upper += 8; - // Start player's pic slide in once the opponent is finished + // Start player's slide in once the opponent is finished if (IsTrainerPicSlideDone(task->tOpponentSpriteId)) { task->tState++; @@ -2335,10 +2426,10 @@ static bool8 Mugshot_WaitPlayerSlide(struct Task *task) SetGpuReg(REG_OFFSET_WIN0H, DISPLAY_WIDTH); SetGpuReg(REG_OFFSET_BLDY, 0); task->tState++; - task->data[3] = 0; - task->data[4] = 0; + task->tTimer = 0; + task->tFadeSpread = 0; sTransitionData->BLDCNT = BLDCNT_TGT1_ALL | BLDCNT_EFFECT_LIGHTEN; - SetVBlankCallback(VBlankCB1_Mugshots); + SetVBlankCallback(VBlankCB_MugshotsFadeOut); } return FALSE; } @@ -2352,16 +2443,18 @@ static bool8 Mugshot_GradualWhiteFade(struct Task *task) sTransitionData->BG0HOFS_Lower -= 8; sTransitionData->BG0HOFS_Upper += 8; - if (task->data[4] < DISPLAY_HEIGHT / 2) - task->data[4] += 2; - if (task->data[4] > DISPLAY_HEIGHT / 2) - task->data[4] = DISPLAY_HEIGHT / 2; + if (task->tFadeSpread < DISPLAY_HEIGHT / 2) + task->tFadeSpread += 2; + if (task->tFadeSpread > DISPLAY_HEIGHT / 2) + task->tFadeSpread = DISPLAY_HEIGHT / 2; - if (++task->data[3] & 1) + if (++task->tTimer & 1) { s16 i; - for (i = 0, active = FALSE; i <= task->data[4]; i++) + for (i = 0, active = FALSE; i <= task->tFadeSpread; i++) { + // Fade starts in middle of screen and + // spreads outwards in both directions. s16 index1 = DISPLAY_HEIGHT / 2 - i; s16 index2 = DISPLAY_HEIGHT / 2 + i; if (gScanlineEffectRegBuffers[0][index1] <= 15) @@ -2377,19 +2470,21 @@ static bool8 Mugshot_GradualWhiteFade(struct Task *task) } } - if (task->data[4] == DISPLAY_HEIGHT / 2 && !active) + if (task->tFadeSpread == DISPLAY_HEIGHT / 2 && !active) task->tState++; sTransitionData->VBlank_DMA++; return FALSE; } +// Set palette to white to replace the scanline white fade +// before the screen fades to black. static bool8 Mugshot_InitFadeWhiteToBlack(struct Task *task) { sTransitionData->VBlank_DMA = FALSE; BlendPalettes(PALETTES_ALL, 16, RGB_WHITE); sTransitionData->BLDCNT = 0xFF; - task->data[3] = 0; + task->tTimer = 0; task->tState++; return TRUE; @@ -2399,9 +2494,9 @@ static bool8 Mugshot_FadeToBlack(struct Task *task) { sTransitionData->VBlank_DMA = FALSE; - task->data[3]++; - memset(gScanlineEffectRegBuffers[0], task->data[3], DISPLAY_HEIGHT * 2); - if (task->data[3] > 15) + task->tTimer++; + memset(gScanlineEffectRegBuffers[0], task->tTimer, DISPLAY_HEIGHT * 2); + if (task->tTimer > 15) task->tState++; sTransitionData->VBlank_DMA++; @@ -2416,7 +2511,7 @@ static bool8 Mugshot_End(struct Task *task) return FALSE; } -static void VBlankCB0_Mugshots(void) +static void VBlankCB_Mugshots(void) { DmaStop(0); VBlankCB_BattleTransition(); @@ -2429,7 +2524,7 @@ static void VBlankCB0_Mugshots(void) DmaSet(0, gScanlineEffectRegBuffers[1], ®_WIN0H, B_TRANS_DMA_FLAGS); } -static void VBlankCB1_Mugshots(void) +static void VBlankCB_MugshotsFadeOut(void) { DmaStop(0); VBlankCB_BattleTransition(); @@ -2447,26 +2542,19 @@ static void HBlankCB_Mugshots(void) REG_BG0HOFS = sTransitionData->BG0HOFS_Upper; } -// data fields for player/opponent sprites in mugshots -#define sState data[0] -#define sOffsetX data[1] -#define sOffsetX2 data[2] -#define sDone data[6] -#define sSlideTableId data[7] - static void Mugshots_CreateTrainerPics(struct Task *task) { struct Sprite *opponentSprite, *playerSprite; s16 mugshotId = task->tMugshotId; task->tOpponentSpriteId = CreateTrainerSprite(sMugshotsTrainerPicIDsTable[mugshotId], - sMugshotsOpponentCoords[mugshotId][0] - 32, - sMugshotsOpponentCoords[mugshotId][1] + 42, - 0, gDecompressionBuffer); + sMugshotsOpponentCoords[mugshotId][0] - 32, + sMugshotsOpponentCoords[mugshotId][1] + 42, + 0, gDecompressionBuffer); task->tPlayerSpriteId = CreateTrainerSprite(PlayerGenderToFrontTrainerPicId(gSaveBlock2Ptr->playerGender), - DISPLAY_WIDTH + 32, - 106, - 0, gDecompressionBuffer); + DISPLAY_WIDTH + 32, + 106, + 0, gDecompressionBuffer); opponentSprite = &gSprites[task->tOpponentSpriteId]; playerSprite = &gSprites[task->tPlayerSpriteId]; @@ -2498,63 +2586,70 @@ static void SpriteCB_MugshotTrainerPic(struct Sprite *sprite) while (sMugshotTrainerPicFuncs[sprite->sState](sprite)); } -static bool8 MugshotTrainerPic_Nothing(struct Sprite *sprite) +// Wait until IncrementTrainerPicState is called +static bool8 MugshotTrainerPic_Pause(struct Sprite *sprite) { return FALSE; } -static bool8 MugshotTrainerPic_SetSlideOffsets(struct Sprite *sprite) +static bool8 MugshotTrainerPic_Init(struct Sprite *sprite) { - s16 offsets1[ARRAY_COUNT(sTrainerPicSlideOffsets1)]; - s16 offsets2[ARRAY_COUNT(sTrainerPicSlideOffsets2)]; + s16 speeds[ARRAY_COUNT(sTrainerPicSlideSpeeds)]; + s16 accels[ARRAY_COUNT(sTrainerPicSlideAccels)]; - memcpy(offsets1, sTrainerPicSlideOffsets1, sizeof(sTrainerPicSlideOffsets1)); - memcpy(offsets2, sTrainerPicSlideOffsets2, sizeof(sTrainerPicSlideOffsets2)); + memcpy(speeds, sTrainerPicSlideSpeeds, sizeof(sTrainerPicSlideSpeeds)); + memcpy(accels, sTrainerPicSlideAccels, sizeof(sTrainerPicSlideAccels)); sprite->sState++; - sprite->sOffsetX = offsets1[sprite->sSlideTableId]; - sprite->sOffsetX2 = offsets2[sprite->sSlideTableId]; + sprite->sSlideSpeed = speeds[sprite->sSlideDir]; + sprite->sSlideAccel = accels[sprite->sSlideDir]; return TRUE; } -// fast slide to around middle screen -static bool8 MugshotTrainerPic_Slide1(struct Sprite *sprite) +static bool8 MugshotTrainerPic_Slide(struct Sprite *sprite) { - sprite->x += sprite->sOffsetX; - if (sprite->sSlideTableId && sprite->x < 133) + sprite->x += sprite->sSlideSpeed; + + // Advance state when pic passes ~40% of screen + if (sprite->sSlideDir && sprite->x < DISPLAY_WIDTH - 107) sprite->sState++; - else if (!sprite->sSlideTableId && sprite->x > 103) + else if (!sprite->sSlideDir && sprite->x > 103) sprite->sState++; return FALSE; } -// slower but accelerating slide -static bool8 MugshotTrainerPic_Slide2(struct Sprite *sprite) +static bool8 MugshotTrainerPic_SlideSlow(struct Sprite *sprite) { - sprite->sOffsetX += sprite->sOffsetX2; - sprite->x += sprite->sOffsetX; - if (sprite->sOffsetX == 0) + // Add acceleration value to speed, then add speed. + // For both sides acceleration is opposite speed, so slide slows down. + sprite->sSlideSpeed += sprite->sSlideAccel; + sprite->x += sprite->sSlideSpeed; + + // Advance state when slide comes to a stop + if (sprite->sSlideSpeed == 0) { sprite->sState++; - sprite->sOffsetX2 = -sprite->sOffsetX2; + sprite->sSlideAccel = -sprite->sSlideAccel; sprite->sDone = TRUE; } return FALSE; } -// Has no practical effect -static bool8 MugshotTrainerPic_Slide3(struct Sprite *sprite) +// Slides trainer pic offscreen. This is never reached, because it's preceded +// by a second MugshotTrainerPic_Pause, and IncrementTrainerPicState is +// only called once per trainer pic. +static bool8 MugshotTrainerPic_SlideOffscreen(struct Sprite *sprite) { - sprite->sOffsetX += sprite->sOffsetX2; - sprite->x += sprite->sOffsetX; + sprite->sSlideSpeed += sprite->sSlideAccel; + sprite->x += sprite->sSlideSpeed; if (sprite->x < -31 || sprite->x > DISPLAY_WIDTH + 31) sprite->sState++; return FALSE; } -static void SetTrainerPicSlideTable(s16 spriteId, s16 arrId) +static void SetTrainerPicSlideDirection(s16 spriteId, s16 dirId) { - gSprites[spriteId].sSlideTableId = arrId; + gSprites[spriteId].sSlideDir = dirId; } static void IncrementTrainerPicState(s16 spriteId) @@ -2568,10 +2663,26 @@ static s16 IsTrainerPicSlideDone(s16 spriteId) } #undef sState -#undef sOffsetX -#undef sOffsetX2 +#undef sSlideSpeed +#undef sSlideAccel #undef sDone -#undef sSlideTableId +#undef sSlideDir +#undef tSinIndex +#undef tTopBannerX +#undef tBottomBannerX +#undef tTimer +#undef tFadeSpread +#undef tOpponentSpriteId +#undef tPlayerSpriteId +#undef tMugshotId + +//-------------------- +// B_TRANSITION_SLICE +//-------------------- + +#define tEffectX data[1] +#define tSpeed data[2] +#define tAccel data[3] static void Task_Slice(u8 taskId) { @@ -2585,8 +2696,8 @@ static bool8 Slice_Init(struct Task *task) InitTransitionData(); ScanlineEffect_Clear(); - task->data[2] = 256; - task->data[3] = 1; + task->tSpeed = 1 << 8; + task->tAccel = 1; sTransitionData->WININ = WININ_WIN0_ALL; sTransitionData->WINOUT = 0; sTransitionData->WIN0V = DISPLAY_HEIGHT; @@ -2608,37 +2719,39 @@ static bool8 Slice_Init(struct Task *task) return TRUE; } -static bool8 Slice_Func2(struct Task *task) +static bool8 Slice_Main(struct Task *task) { u16 i; sTransitionData->VBlank_DMA = FALSE; - task->data[1] += (task->data[2] >> 8); - if (task->data[1] > DISPLAY_WIDTH) - task->data[1] = DISPLAY_WIDTH; - if (task->data[2] <= 0xFFF) - task->data[2] += task->data[3]; - if (task->data[3] < 128) - task->data[3] <<= 1; // multiplying by two + task->tEffectX += (task->tSpeed >> 8); + if (task->tEffectX > DISPLAY_WIDTH) + task->tEffectX = DISPLAY_WIDTH; + if (task->tSpeed <= 0xFFF) + task->tSpeed += task->tAccel; + if (task->tAccel < 128) + task->tAccel <<= 1; // multiplying by two for (i = 0; i < DISPLAY_HEIGHT; i++) { u16 *storeLoc1 = &gScanlineEffectRegBuffers[0][i]; u16 *storeLoc2 = &gScanlineEffectRegBuffers[0][i + DISPLAY_HEIGHT]; - if (i & 1) + + // Alternate rows + if (i % 2) { - *storeLoc1 = sTransitionData->cameraX + task->data[1]; - *storeLoc2 = DISPLAY_WIDTH - task->data[1]; + *storeLoc1 = sTransitionData->cameraX + task->tEffectX; + *storeLoc2 = DISPLAY_WIDTH - task->tEffectX; } else { - *storeLoc1 = sTransitionData->cameraX - task->data[1]; - *storeLoc2 = (task->data[1] << 8) | (DISPLAY_WIDTH + 1); + *storeLoc1 = sTransitionData->cameraX - task->tEffectX; + *storeLoc2 = (task->tEffectX << 8) | (DISPLAY_WIDTH + 1); } } - if (task->data[1] >= DISPLAY_WIDTH) + if (task->tEffectX >= DISPLAY_WIDTH) task->tState++; sTransitionData->VBlank_DMA++; @@ -2676,6 +2789,20 @@ static void HBlankCB_Slice(void) } } +#undef tEffectX +#undef tSpeed +#undef tAccel + +//-------------------------- +// B_TRANSITION_SHRED_SPLIT +//-------------------------- + +// Data starts at 4. Possible it shared data +// with Slice above, which ends at 3. +#define tDelayTimer data[4] +#define tExtent data[5] +#define tDelay data[6] + static void Task_ShredSplit(u8 taskId) { while (sShredSplit_Funcs[gTasks[taskId].tState](&gTasks[taskId])); @@ -2703,9 +2830,9 @@ static bool8 ShredSplit_Init(struct Task *task) gScanlineEffectRegBuffers[0][DISPLAY_HEIGHT * 4 + i] = 1; } - task->data[4] = 0; - task->data[5] = 0; - task->data[6] = 7; + task->tDelayTimer = 0; + task->tExtent = 0; + task->tDelay = 7; EnableInterrupts(INTR_FLAG_HBLANK); @@ -2716,37 +2843,38 @@ static bool8 ShredSplit_Init(struct Task *task) return TRUE; } -static bool8 ShredSplit_Func2(struct Task *task) +static bool8 ShredSplit_Main(struct Task *task) { u16 i, j, k; - u8 arr1[ARRAY_COUNT(gUnknown_085C8C64)]; - s16 arr2[ARRAY_COUNT(gUnknown_085C8C66)]; - u8 var; + u8 baseY[ARRAY_COUNT(sShredSplit_SectionYCoords)]; + s16 moveDirs[ARRAY_COUNT(sShredSplit_SectionMoveDirs)]; + u8 linesFinished; u16 *ptr4, *ptr3, *ptr1, *ptr2; - s16 unkVar; + s16 y; - memcpy(arr1, gUnknown_085C8C64, sizeof(arr1)); - memcpy(arr2, gUnknown_085C8C66, sizeof(arr2)); + memcpy(baseY, sShredSplit_SectionYCoords, sizeof(baseY)); + memcpy(moveDirs, sShredSplit_SectionMoveDirs, sizeof(moveDirs)); sTransitionData->VBlank_DMA = FALSE; - var = 0; + linesFinished = 0; - for (i = 0; i <= task->data[5]; i++) + for (i = 0; i <= task->tExtent; i++) { + // Slide half of the pixel rows (alternating) right for (j = 0; j < 2; j++) { for (k = 0; k < 2; k++) { - unkVar = (arr1[j]) + (arr2[k] * -(i) * 2); - if (unkVar >= 0 && (unkVar != 79 || j != 1)) + y = baseY[j] + (moveDirs[k] * -i * 2); + if (y >= 0 && (y != DISPLAY_HEIGHT / 2 - 1 || j != 1)) { - ptr4 = &gScanlineEffectRegBuffers[0][unkVar + DISPLAY_HEIGHT * 2]; - ptr3 = &gScanlineEffectRegBuffers[0][unkVar + DISPLAY_HEIGHT * 3]; - ptr1 = &gScanlineEffectRegBuffers[0][unkVar + DISPLAY_HEIGHT * 4]; + ptr4 = &gScanlineEffectRegBuffers[0][y + DISPLAY_HEIGHT * 2]; + ptr3 = &gScanlineEffectRegBuffers[0][y + DISPLAY_HEIGHT * 3]; + ptr1 = &gScanlineEffectRegBuffers[0][y + DISPLAY_HEIGHT * 4]; if (*ptr4 >= DISPLAY_WIDTH) { *ptr4 = DISPLAY_WIDTH; - var++; + linesFinished++; } else { @@ -2756,8 +2884,8 @@ static bool8 ShredSplit_Func2(struct Task *task) if (*ptr3 <= 0xFFF) *ptr3 += *ptr1; } - ptr2 = &gScanlineEffectRegBuffers[0][unkVar]; - ptr3 = &gScanlineEffectRegBuffers[0][unkVar + DISPLAY_HEIGHT]; + ptr2 = &gScanlineEffectRegBuffers[0][y]; + ptr3 = &gScanlineEffectRegBuffers[0][y + DISPLAY_HEIGHT]; *ptr2 = sTransitionData->cameraX + *ptr4; *ptr3 = DISPLAY_WIDTH - *ptr4; @@ -2767,20 +2895,21 @@ static bool8 ShredSplit_Func2(struct Task *task) } } + // Slide the other half of the rows left for (j = 0; j < 2; j++) { for (k = 0; k < 2; k++) { - unkVar = (arr1[j] + 1) + (arr2[k] * -(i) * 2); - if (unkVar <= DISPLAY_HEIGHT && (unkVar != DISPLAY_HEIGHT / 2 || j != 1)) + y = baseY[j] + 1 + (moveDirs[k] * -i * 2); + if (y <= DISPLAY_HEIGHT && (y != DISPLAY_HEIGHT / 2 || j != 1)) { - ptr4 = &gScanlineEffectRegBuffers[0][unkVar + DISPLAY_HEIGHT * 2]; - ptr3 = &gScanlineEffectRegBuffers[0][unkVar + DISPLAY_HEIGHT * 3]; - ptr1 = &gScanlineEffectRegBuffers[0][unkVar + DISPLAY_HEIGHT * 4]; + ptr4 = &gScanlineEffectRegBuffers[0][y + DISPLAY_HEIGHT * 2]; + ptr3 = &gScanlineEffectRegBuffers[0][y + DISPLAY_HEIGHT * 3]; + ptr1 = &gScanlineEffectRegBuffers[0][y + DISPLAY_HEIGHT * 4]; if (*ptr4 >= DISPLAY_WIDTH) { *ptr4 = DISPLAY_WIDTH; - var++; + linesFinished++; } else { @@ -2790,8 +2919,8 @@ static bool8 ShredSplit_Func2(struct Task *task) if (*ptr3 <= 0xFFF) *ptr3 += *ptr1; } - ptr2 = &gScanlineEffectRegBuffers[0][unkVar]; - ptr3 = &gScanlineEffectRegBuffers[0][unkVar + DISPLAY_HEIGHT]; + ptr2 = &gScanlineEffectRegBuffers[0][y]; + ptr3 = &gScanlineEffectRegBuffers[0][y + DISPLAY_HEIGHT]; *ptr2 = sTransitionData->cameraX - *ptr4; *ptr3 = (*ptr4 << 8) | (DISPLAY_WIDTH + 1); @@ -2802,11 +2931,19 @@ static bool8 ShredSplit_Func2(struct Task *task) } } - if (--task->data[4] < 0) - task->data[4] = 0; - if (task->data[4] <= 0 && task->data[5] + 1 <= 20) - task->data[4] = task->data[6], task->data[5]++; - if (var >= DISPLAY_HEIGHT) + // Count down to next move + if (--task->tDelayTimer < 0) + task->tDelayTimer = 0; + + // Try increase effect's extent + if (task->tDelayTimer <= 0 && task->tExtent + 1 <= DISPLAY_HEIGHT / 8) + { + task->tDelayTimer = task->tDelay; + task->tExtent++; + } + + // All lines have reached screen width, move on. + if (linesFinished >= DISPLAY_HEIGHT) task->tState++; sTransitionData->VBlank_DMA++; @@ -2817,7 +2954,8 @@ static bool8 ShredSplit_Func2(struct Task *task) // is always false, resulting in the game being stuck in an infinite loop. // It's possible this transition is only partially // done and the second part was left out. -static bool8 ShredSplit_Func3(struct Task *task) +// In any case removing or bypassing this state allows the transition to finish. +static bool8 ShredSplit_BrokenCheck(struct Task *task) { u16 i; bool32 done = TRUE; @@ -2826,7 +2964,7 @@ static bool8 ShredSplit_Func3(struct Task *task) for (i = 0; i < DISPLAY_HEIGHT; i++) { if (gScanlineEffectRegBuffers[1][i] != DISPLAY_WIDTH && gScanlineEffectRegBuffers[1][i] != checkVar2) - done = FALSE; // a break statement should be put here + done = FALSE; } if (done == TRUE) @@ -2843,16 +2981,32 @@ static bool8 ShredSplit_End(struct Task *task) return FALSE; } -static void Task_Blackhole1(u8 taskId) +#undef tDelayTimer +#undef tExtent +#undef tDelay + +//----------------------------------------------------------- +// B_TRANSITION_BLACKHOLE and B_TRANSITION_BLACKHOLE_PULSATE +//----------------------------------------------------------- + +#define tRadius data[1] +#define tGrowSpeed data[2] +#define tSinIndex data[5] +#define tVibrateId data[6] +#define tAmplitude data[6] // Used differently by the two transitions +#define tFlag data[7] // Used generally to indicate an action has taken place. + +static void Task_Blackhole(u8 taskId) { - while (sBlackhole1_Funcs[gTasks[taskId].tState](&gTasks[taskId])); + while (sBlackhole_Funcs[gTasks[taskId].tState](&gTasks[taskId])); } -static void Task_Blackhole2(u8 taskId) +static void Task_BlackholePulsate(u8 taskId) { - while (sBlackhole2_Funcs[gTasks[taskId].tState](&gTasks[taskId])); + while (sBlackholePulsate_Funcs[gTasks[taskId].tState](&gTasks[taskId])); } +// Init is shared by both transitions static bool8 Blackhole_Init(struct Task *task) { s32 i; @@ -2868,19 +3022,19 @@ static bool8 Blackhole_Init(struct Task *task) for (i = 0; i < DISPLAY_HEIGHT; i++) gScanlineEffectRegBuffers[1][i] = 0; - SetVBlankCallback(VBlankCB1_BigPokeball); + SetVBlankCallback(VBlankCB_CircularMask); task->tState++; - task->data[1] = 1; - task->data[2] = 0x100; - task->tFuncState = 0; + task->tRadius = 1; + task->tGrowSpeed = 1 << 8; + task->tFlag = FALSE; return FALSE; } -static bool8 Blackhole1_Func3(struct Task *task) +static bool8 Blackhole_GrowEnd(struct Task *task) { - if (task->tFuncState == 1) + if (task->tFlag == TRUE) { DmaStop(0); SetVBlankCallback(NULL); @@ -2889,16 +3043,16 @@ static bool8 Blackhole1_Func3(struct Task *task) else { sTransitionData->VBlank_DMA = FALSE; - if (task->data[2] < 1024) - task->data[2] += 128; - if (task->data[1] < DISPLAY_HEIGHT) - task->data[1] += (task->data[2] >> 8); - if (task->data[1] > DISPLAY_HEIGHT) - task->data[1] = DISPLAY_HEIGHT; - sub_814A014(gScanlineEffectRegBuffers[0], 120, 80, task->data[1]); - if (task->data[1] == DISPLAY_HEIGHT) + if (task->tGrowSpeed < 1024) + task->tGrowSpeed += 128; + if (task->tRadius < DISPLAY_HEIGHT) + task->tRadius += task->tGrowSpeed >> 8; + if (task->tRadius > DISPLAY_HEIGHT) + task->tRadius = DISPLAY_HEIGHT; + SetCircularMask(gScanlineEffectRegBuffers[0], DISPLAY_WIDTH / 2, DISPLAY_HEIGHT / 2, task->tRadius); + if (task->tRadius == DISPLAY_HEIGHT) { - task->tFuncState = 1; + task->tFlag = TRUE; FadeScreenBlack(); } else @@ -2910,73 +3064,89 @@ static bool8 Blackhole1_Func3(struct Task *task) return FALSE; } -static bool8 Blackhole1_Func2(struct Task *task) +static bool8 Blackhole_Vibrate(struct Task *task) { sTransitionData->VBlank_DMA = FALSE; - if (task->tFuncState == 0) + if (task->tFlag == FALSE) { - task->tFuncState++; - task->data[1] = 0x30; - task->data[6] = 0; + task->tFlag++; + task->tRadius = 48; + task->tVibrateId = 0; } - task->data[1] += gUnknown_085C8C80[task->data[6]]; - task->data[6] = (task->data[6] + 1) % 2; - sub_814A014(gScanlineEffectRegBuffers[0], 120, 80, task->data[1]); - if (task->data[1] < 9) + task->tRadius += sBlackhole_Vibrations[task->tVibrateId]; + task->tVibrateId = (task->tVibrateId + 1) % (int)ARRAY_COUNT(sBlackhole_Vibrations); + SetCircularMask(gScanlineEffectRegBuffers[0], DISPLAY_WIDTH / 2, DISPLAY_HEIGHT / 2, task->tRadius); + if (task->tRadius < 9) { task->tState++; - task->tFuncState = 0; + task->tFlag = FALSE; } sTransitionData->VBlank_DMA++; return FALSE; } -static bool8 Blackhole2_Func2(struct Task *task) +static bool8 BlackholePulsate_Main(struct Task *task) { u16 index; // should be s16 I think s16 amplitude; sTransitionData->VBlank_DMA = FALSE; - if (task->tFuncState == 0) + if (task->tFlag == FALSE) { - task->tFuncState++; - task->data[5] = 2; - task->data[6] = 2; + task->tFlag++; + task->tSinIndex = 2; + task->tAmplitude = 2; } - if (task->data[1] > DISPLAY_HEIGHT) - task->data[1] = DISPLAY_HEIGHT; - sub_814A014(gScanlineEffectRegBuffers[0], 120, 80, task->data[1]); - if (task->data[1] == DISPLAY_HEIGHT) + if (task->tRadius > DISPLAY_HEIGHT) + task->tRadius = DISPLAY_HEIGHT; + + SetCircularMask(gScanlineEffectRegBuffers[0], DISPLAY_WIDTH / 2, DISPLAY_HEIGHT / 2, task->tRadius); + if (task->tRadius == DISPLAY_HEIGHT) { DmaStop(0); FadeScreenBlack(); DestroyTask(FindTaskIdByFunc(task->func)); } - index = task->data[5]; - if ((task->data[5] & 0xFF) <= 128) + index = task->tSinIndex; + if ((task->tSinIndex & 0xFF) <= 128) { - amplitude = task->data[6]; - task->data[5] += 8; + amplitude = task->tAmplitude; + task->tSinIndex += 8; } else { - amplitude = task->data[6] - 1; - task->data[5] += 16; + amplitude = task->tAmplitude - 1; + task->tSinIndex += 16; } - task->data[1] += Sin(index & 0xFF, amplitude); + task->tRadius += Sin(index & 0xFF, amplitude); - if (task->data[1] <= 0) - task->data[1] = 1; - if (task->data[5] > 0xFE) - task->data[5] >>= 8, task->data[6]++; + if (task->tRadius <= 0) + task->tRadius = 1; + + if (task->tSinIndex >= 0xFF) + { + task->tSinIndex >>= 8; + task->tAmplitude++; + } sTransitionData->VBlank_DMA++; return FALSE; } +#undef tRadius +#undef tGrowSpeed +#undef tSinIndex +#undef tVibrateId +#undef tAmplitude +#undef tFlag + +//--------------------------------- +// B_TRANSITION_RECTANGULAR_SPIRAL +//--------------------------------- + static void Task_RectangularSpiral(u8 taskId) { while (sRectangularSpiral_Funcs[gTasks[taskId].tState](&gTasks[taskId])); @@ -2989,40 +3159,44 @@ static bool8 RectangularSpiral_Init(struct Task *task) GetBg0TilesDst(&tilemap, &tileset); CpuCopy16(sShrinkingBoxTileset, tileset, 0x20); CpuCopy16(sShrinkingBoxTileset + 0x70, tileset + 0x20, 0x20); - CpuFill16(0xF000, tilemap, BG_SCREEN_SIZE); + CpuFill16(0xF0 << 8, tilemap, BG_SCREEN_SIZE); LoadPalette(sFieldEffectPal_Pokeball, 0xF0, sizeof(sFieldEffectPal_Pokeball)); task->data[3] = 1; task->tState++; - sRectangularSpiralTransition[0].field_0 = 0; - sRectangularSpiralTransition[0].field_2 = -1; - sRectangularSpiralTransition[0].field_4 = 1; - sRectangularSpiralTransition[0].field_6 = 308; - sRectangularSpiralTransition[0].field_8 = 0; + // Top left + sRectangularSpiralLines[0].state = 0; + sRectangularSpiralLines[0].position = -1; + sRectangularSpiralLines[0].moveIdx = 1; + sRectangularSpiralLines[0].skipPosition = 308; + sRectangularSpiralLines[0].field_8 = 0; - sRectangularSpiralTransition[1].field_0 = 0; - sRectangularSpiralTransition[1].field_2 = -1; - sRectangularSpiralTransition[1].field_4 = 1; - sRectangularSpiralTransition[1].field_6 = 308; - sRectangularSpiralTransition[1].field_8 = 0; + // Bottom right + sRectangularSpiralLines[1].state = 0; + sRectangularSpiralLines[1].position = -1; + sRectangularSpiralLines[1].moveIdx = 1; + sRectangularSpiralLines[1].skipPosition = 308; + sRectangularSpiralLines[1].field_8 = 0; - sRectangularSpiralTransition[2].field_0 = 0; - sRectangularSpiralTransition[2].field_2 = -3; - sRectangularSpiralTransition[2].field_4 = 1; - sRectangularSpiralTransition[2].field_6 = 307; - sRectangularSpiralTransition[2].field_8 = 0; + // Top right + sRectangularSpiralLines[2].state = 0; + sRectangularSpiralLines[2].position = -3; + sRectangularSpiralLines[2].moveIdx = 1; + sRectangularSpiralLines[2].skipPosition = 307; + sRectangularSpiralLines[2].field_8 = 0; - sRectangularSpiralTransition[3].field_0 = 0; - sRectangularSpiralTransition[3].field_2 = -3; - sRectangularSpiralTransition[3].field_4 = 1; - sRectangularSpiralTransition[3].field_6 = 307; - sRectangularSpiralTransition[3].field_8 = 0; + // Bottom left + sRectangularSpiralLines[3].state = 0; + sRectangularSpiralLines[3].position = -3; + sRectangularSpiralLines[3].moveIdx = 1; + sRectangularSpiralLines[3].skipPosition = 307; + sRectangularSpiralLines[3].field_8 = 0; return FALSE; } -static bool8 RectangularSpiral_Func2(struct Task *task) +static bool8 RectangularSpiral_Main(struct Task *task) { u16 *tilemap, *tileset; u8 i; @@ -3031,24 +3205,28 @@ static bool8 RectangularSpiral_Func2(struct Task *task) GetBg0TilesDst(&tilemap, &tileset); + // Draw 2 tiles at a time for each spiral line for (i = 0; i < 2; i++) { - for (j = 0; j < ARRAY_COUNT(sRectangularSpiralTransition); j++) + for (j = 0; j < ARRAY_COUNT(sRectangularSpiralLines); j++) { - s16 var = 0, var2 = 0; - s32 var3 = 0; + s16 position = 0; + s16 x = 0, y = 0; - if (sub_8149048(gUnknown_085C8D38[j / 2], &sRectangularSpiralTransition[j])) + if (UpdateRectangularSpiralLine(sRectangularSpiral_MoveDataTables[j / 2], &sRectangularSpiralLines[j])) { + // The line moved to a new position, draw the tile. done = FALSE; - var = sRectangularSpiralTransition[j].field_2; + position = sRectangularSpiralLines[j].position; + + // Invert position for the two bottom lines if ((j % 2) == 1) - var = 0x27D - var; + position = 637 - position; - var2 = var % 32; - var3 = var / 32; + x = position % 32; + y = position / 32; - SET_TILEMAP_TILE(tilemap, var3, var2, 0xF002); + SET_TILE(tilemap, y, x, 2); } } } @@ -3066,69 +3244,77 @@ static bool8 RectangularSpiral_End(struct Task *task) return FALSE; } -static bool16 sub_8149048(const s16 * const *arg0, struct StructRectangularSpiral *arg1) +// Returns TRUE if a tile should be drawn, FALSE otherwise +static bool16 UpdateRectangularSpiralLine(const s16 * const *moveDataTable, struct RectangularSpiralLine *line) { - const s16 *array = arg0[arg1->field_0]; - if (array[arg1->field_4] == -1) + const s16 *moveData = moveDataTable[line->state]; + if (moveData[line->moveIdx] == SPIRAL_END) return FALSE; - // ?? - sUnusedRectangularSpiralVar = array[0]; - sUnusedRectangularSpiralVar = array[1]; - sUnusedRectangularSpiralVar = array[2]; - sUnusedRectangularSpiralVar = array[3]; + // Presumably saving data for debug. + sDebug_RectangularSpiralData = moveData[0]; + sDebug_RectangularSpiralData = moveData[1]; + sDebug_RectangularSpiralData = moveData[2]; + sDebug_RectangularSpiralData = moveData[3]; - switch (array[0]) + switch (moveData[0]) { case 1: - arg1->field_2 += 0x1; + line->position += 1; break; case 2: - arg1->field_2 -= 0x1; + line->position -= 1; break; case 3: - arg1->field_2 -= 0x20; + line->position -= 32; break; case 4: - arg1->field_2 += 0x20; + line->position += 32; break; } - if (arg1->field_2 > 0x27F || array[arg1->field_4] == -1) + // Below check is never true. + // SPIRAL_END was already checked, and position is never >= 640 + if (line->position >= 640 || moveData[line->moveIdx] == SPIRAL_END) return FALSE; - if (arg1->field_8 == 0 && array[arg1->field_4] == -2) + if (line->field_8 == 0 && moveData[line->moveIdx] == SPIRAL_SKIP) { - arg1->field_8 = 1; - arg1->field_4 = 1; - arg1->field_2 = arg1->field_6; - arg1->field_0 = 4; + line->field_8 = 1; + line->moveIdx = 1; + line->position = line->skipPosition; + line->state = 4; } - if (arg1->field_2 == array[arg1->field_4]) + if (line->position == moveData[line->moveIdx]) { - (arg1->field_0)++; - if (arg1->field_8 == 1) + line->state++; + if (line->field_8 == 1) { - if (arg1->field_0 > 7) + if (line->state > 7) { - (arg1->field_4)++; - (arg1->field_0) = 4; + line->moveIdx++; + line->state = 4; } } else { - if (arg1->field_0 > 3) + if (line->state > 3) { - (arg1->field_4)++; - (arg1->field_0) = 0; + line->moveIdx++; + line->state = 0; } } } - return TRUE; } +//---------------------- +// B_TRANSITION_GROUDON +//---------------------- + +#define tTimer data[1] + static void Task_Groudon(u8 taskId) { while (sGroudon_Funcs[gTasks[taskId].tState](&gTasks[taskId])); @@ -3144,21 +3330,21 @@ static bool8 Groudon_Init(struct Task *task) LZ77UnCompVram(sGroudon_Tilemap, tilemap); task->tState++; - task->data[1] = 0; + task->tTimer = 0; return FALSE; } -static bool8 Groudon_PalettePulsate(struct Task *task) +static bool8 Groudon_PaletteFlash(struct Task *task) { - if (task->data[1] % 3 == 0) + if (task->tTimer % 3 == 0) { - u16 var = (task->data[1] % 30) / 3; - LoadPalette(sGroudon1_Palette + (var * 16), 0xF0, 0x20); + u16 offset = (task->tTimer % 30) / 3; + LoadPalette(&sGroudon1_Palette[offset * 16], 0xF0, 0x20); } - if (++task->data[1] > 58) + if (++task->tTimer > 58) { task->tState++; - task->data[1] = 0; + task->tTimer = 0; } return FALSE; @@ -3166,29 +3352,38 @@ static bool8 Groudon_PalettePulsate(struct Task *task) static bool8 Groudon_PaletteBrighten(struct Task *task) { - if (task->data[1] % 5 == 0) + if (task->tTimer % 5 == 0) { - s16 var = task->data[1] / 5; - LoadPalette(sGroudon2_Palette + (var * 16), 0xF0, 0x20); + s16 offset = task->tTimer / 5; + LoadPalette(&sGroudon2_Palette[offset * 16], 0xF0, 0x20); } - if (++task->data[1] > 68) + if (++task->tTimer > 68) { task->tState++; - task->data[1] = 0; + task->tTimer = 0; task->tEndDelay = 30; } return FALSE; } +#undef tTimer #undef tEndDelay +//----------------------- +// B_TRANSITION_RAYQUAZA +//----------------------- + +#define tTimer data[1] +#define tGrowSpeed data[2] // Shared from B_TRANSITION_BLACKHOLE +#define tFlag data[7] // Shared from B_TRANSITION_BLACKHOLE + static void Task_Rayquaza(u8 taskId) { while (sRayquaza_Funcs[gTasks[taskId].tState](&gTasks[taskId])); } -static bool8 Rayquaza_Func3(struct Task *task) +static bool8 Rayquaza_Init(struct Task *task) { u16 *tilemap, *tileset; u16 i; @@ -3201,9 +3396,9 @@ static bool8 Rayquaza_Func3(struct Task *task) CpuFill16(0, tilemap, BG_SCREEN_SIZE); CpuCopy16(sRayquaza_Tileset, tileset, 0x2000); - sTransitionData->field_20 = 0; + sTransitionData->counter = 0; task->tState++; - LoadPalette(sRayquaza_Palette + 0x50, 0xF0, 0x20); + LoadPalette(&sRayquaza_Palette[0x50], 0xF0, 0x20); for (i = 0; i < DISPLAY_HEIGHT; i++) { @@ -3215,7 +3410,7 @@ static bool8 Rayquaza_Func3(struct Task *task) return FALSE; } -static bool8 Rayquaza_Func4(struct Task *task) +static bool8 Rayquaza_SetGfx(struct Task *task) { u16 *tilemap, *tileset; @@ -3225,47 +3420,46 @@ static bool8 Rayquaza_Func4(struct Task *task) return FALSE; } -static bool8 Rayquaza_Func5(struct Task *task) +static bool8 Rayquaza_PaletteFlash(struct Task *task) { - if ((task->data[1] % 4) == 0) + if ((task->tTimer % 4) == 0) { - u16 value = task->data[1] / 4; + u16 value = task->tTimer / 4; const u16 *palPtr = &sRayquaza_Palette[(value + 5) * 16]; LoadPalette(palPtr, 0xF0, 0x20); } - if (++task->data[1] > 40) + if (++task->tTimer > 40) { task->tState++; - task->data[1] = 0; + task->tTimer = 0; } return FALSE; } -static bool8 Rayquaza_Func6(struct Task *task) +static bool8 Rayquaza_FadeToBlack(struct Task *task) { - if (++task->data[1] > 20) + if (++task->tTimer > 20) { task->tState++; - task->data[1] = 0; + task->tTimer = 0; BeginNormalPaletteFade(PALETTES_OBJECTS | (1 << 15), 2, 0, 16, RGB_BLACK); } return FALSE; } -static bool8 Rayquaza_Func7(struct Task *task) +static bool8 Rayquaza_WaitFade(struct Task *task) { if (!gPaletteFade.active) { - sTransitionData->field_20 = 1; + sTransitionData->counter = 1; task->tState++; } - return FALSE; } -static bool8 Rayquaza_Func8(struct Task *task) +static bool8 Rayquaza_SetBlack(struct Task *task) { BlendPalettes(PALETTES_BG & ~(1 << 15), 8, RGB_BLACK); BlendPalettes(PALETTES_OBJECTS | (1 << 15), 0, RGB_BLACK); @@ -3274,15 +3468,15 @@ static bool8 Rayquaza_Func8(struct Task *task) return FALSE; } -static bool8 Rayquaza_Func9(struct Task *task) +static bool8 Rayquaza_TriRing(struct Task *task) { - if ((task->data[1] % 3) == 0) + if ((task->tTimer % 3) == 0) { - u16 value = task->data[1] / 3; + u16 value = task->tTimer / 3; const u16 *palPtr = &sRayquaza_Palette[(value + 0) * 16]; LoadPalette(palPtr, 0xF0, 0x20); } - if (++task->data[1] >= 40) + if (++task->tTimer >= 40) { u16 i; @@ -3294,10 +3488,10 @@ static bool8 Rayquaza_Func9(struct Task *task) for (i = 0; i < DISPLAY_HEIGHT; i++) gScanlineEffectRegBuffers[1][i] = 0; - SetVBlankCallback(VBlankCB1_BigPokeball); + SetVBlankCallback(VBlankCB_CircularMask); task->tState++; - task->data[2] = 0x100; - task->tFuncState = 0; + task->tGrowSpeed = 1 << 8; + task->tFlag = FALSE; ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG0_ON); } @@ -3311,9 +3505,9 @@ static void VBlankCB_Rayquaza(void) DmaStop(0); VBlankCB_BattleTransition(); - if (sTransitionData->field_20 == 0) + if (sTransitionData->counter == 0) dmaSrc = gScanlineEffectRegBuffers[0]; - else if (sTransitionData->field_20 == 1) + else if (sTransitionData->counter == 1) dmaSrc = gScanlineEffectRegBuffers[1]; else dmaSrc = gScanlineEffectRegBuffers[0]; @@ -3321,12 +3515,28 @@ static void VBlankCB_Rayquaza(void) DmaSet(0, dmaSrc, ®_BG0VOFS, B_TRANS_DMA_FLAGS); } -static void Task_WhiteFade(u8 taskId) +#undef tTimer +#undef tGrowSpeed +#undef tFlag + +//------------------------------ +// B_TRANSITION_WHITE_BARS_FADE +//------------------------------ + +#define sFade data[0] +#define sFinished data[1] +#define sDestroyAttempts data[2] +#define sDelay data[5] +#define sIsMainSprite data[6] + +#define FADE_TARGET (16 << 8) + +static void Task_WhiteBarsFade(u8 taskId) { - while (sWhiteFade_Funcs[gTasks[taskId].tState](&gTasks[taskId])); + while (sWhiteBarsFade_Funcs[gTasks[taskId].tState](&gTasks[taskId])); } -static bool8 WhiteFade_Init(struct Task *task) +static bool8 WhiteBarsFade_Init(struct Task *task) { u16 i; @@ -3346,37 +3556,40 @@ static bool8 WhiteFade_Init(struct Task *task) } EnableInterrupts(INTR_FLAG_HBLANK); - SetHBlankCallback(HBlankCB_WhiteFade); - SetVBlankCallback(VBlankCB0_WhiteFade); + SetHBlankCallback(HBlankCB_WhiteBarsFade); + SetVBlankCallback(VBlankCB_WhiteBarsFade); task->tState++; return FALSE; } -static bool8 WhiteFade_Func2(struct Task *task) +static bool8 WhiteBarsFade_StartBars(struct Task *task) { s16 i, posY; - s16 arr1[ARRAY_COUNT(sUnknown_085C8DA0)]; + s16 delays[ARRAY_COUNT(sWhiteBarsFade_StartDelays)]; struct Sprite *sprite; + memcpy(delays, sWhiteBarsFade_StartDelays, sizeof(sWhiteBarsFade_StartDelays)); - memcpy(arr1, sUnknown_085C8DA0, sizeof(sUnknown_085C8DA0)); - for (i = 0, posY = 0; i < 8; i++, posY += 20) + for (i = 0, posY = 0; i < NUM_WHITE_BARS; i++, posY += DISPLAY_HEIGHT / NUM_WHITE_BARS) { - sprite = &gSprites[CreateInvisibleSprite(sub_8149864)]; + sprite = &gSprites[CreateInvisibleSprite(SpriteCB_WhiteBarFade)]; sprite->x = DISPLAY_WIDTH; sprite->y = posY; - sprite->data[5] = arr1[i]; + sprite->sDelay = delays[i]; } - sprite->data[6]++; + + // Set on one sprite only. This one will enable the DMA + // copy in VBlank and wait for the others to destroy. + sprite->sIsMainSprite++; task->tState++; return FALSE; } -static bool8 WhiteFade_Func3(struct Task *task) +static bool8 WhiteBarsFade_WaitBars(struct Task *task) { sTransitionData->VBlank_DMA = 0; - if (sTransitionData->field_20 > 7) + if (sTransitionData->counter >= NUM_WHITE_BARS) { BlendPalettes(PALETTES_ALL, 16, RGB_WHITE); task->tState++; @@ -3384,7 +3597,7 @@ static bool8 WhiteFade_Func3(struct Task *task) return FALSE; } -static bool8 WhiteFade_Func4(struct Task *task) +static bool8 WhiteBarsFade_BlendToBlack(struct Task *task) { sTransitionData->VBlank_DMA = 0; @@ -3397,23 +3610,23 @@ static bool8 WhiteFade_Func4(struct Task *task) sTransitionData->BLDCNT = 0xFF; sTransitionData->WININ = WININ_WIN0_ALL; - SetVBlankCallback(VBlankCB1_WhiteFade); + SetVBlankCallback(VBlankCB_WhiteBarsFade_Blend); task->tState++; return FALSE; } -static bool8 WhiteFade_End(struct Task *task) +static bool8 WhiteBarsFade_End(struct Task *task) { if (++sTransitionData->BLDY > 16) { FadeScreenBlack(); - DestroyTask(FindTaskIdByFunc(Task_WhiteFade)); + DestroyTask(FindTaskIdByFunc(Task_WhiteBarsFade)); } return FALSE; } -static void VBlankCB0_WhiteFade(void) +static void VBlankCB_WhiteBarsFade(void) { DmaStop(0); VBlankCB_BattleTransition(); @@ -3426,7 +3639,7 @@ static void VBlankCB0_WhiteFade(void) DmaSet(0, &gScanlineEffectRegBuffers[1][DISPLAY_HEIGHT], ®_WIN0H, B_TRANS_DMA_FLAGS); } -static void VBlankCB1_WhiteFade(void) +static void VBlankCB_WhiteBarsFade_Blend(void) { VBlankCB_BattleTransition(); REG_BLDY = sTransitionData->BLDY; @@ -3437,17 +3650,17 @@ static void VBlankCB1_WhiteFade(void) REG_WIN0V = sTransitionData->WIN0V; } -static void HBlankCB_WhiteFade(void) +static void HBlankCB_WhiteBarsFade(void) { REG_BLDY = gScanlineEffectRegBuffers[1][REG_VCOUNT]; } -static void sub_8149864(struct Sprite *sprite) +static void SpriteCB_WhiteBarFade(struct Sprite *sprite) { - if (sprite->data[5]) + if (sprite->sDelay) { - sprite->data[5]--; - if (sprite->data[6]) + sprite->sDelay--; + if (sprite->sIsMainSprite) sTransitionData->VBlank_DMA = 1; } else @@ -3455,36 +3668,51 @@ static void sub_8149864(struct Sprite *sprite) u16 i; u16* ptr1 = &gScanlineEffectRegBuffers[0][sprite->y]; u16* ptr2 = &gScanlineEffectRegBuffers[0][sprite->y + DISPLAY_HEIGHT]; - for (i = 0; i < 20; i++) + for (i = 0; i < DISPLAY_HEIGHT / NUM_WHITE_BARS; i++) { - ptr1[i] = sprite->data[0] >> 8; - ptr2[i] = (u8)(sprite->x); + ptr1[i] = sprite->sFade >> 8; + ptr2[i] = (u8)sprite->x; } - if (sprite->x == 0 && sprite->data[0] == 0x1000) - sprite->data[1] = 1; + if (sprite->x == 0 && sprite->sFade == FADE_TARGET) + sprite->sFinished = TRUE; sprite->x -= 16; - sprite->data[0] += 0x80; + sprite->sFade += FADE_TARGET / 32; if (sprite->x < 0) sprite->x = 0; - if (sprite->data[0] > 0x1000) - sprite->data[0] = 0x1000; + if (sprite->sFade > FADE_TARGET) + sprite->sFade = FADE_TARGET; - if (sprite->data[6]) + if (sprite->sIsMainSprite) sTransitionData->VBlank_DMA = 1; - if (sprite->data[1]) + if (sprite->sFinished) { - if (sprite->data[6] == 0 || (sTransitionData->field_20 > 6 && sprite->data[2]++ > 7)) + // If not the main sprite, destroy self. Otherwise, wait until the + // others have destroyed themselves, or until enough time has elapsed. + if (!sprite->sIsMainSprite || (sTransitionData->counter >= NUM_WHITE_BARS - 1 && sprite->sDestroyAttempts++ > 7)) { - sTransitionData->field_20++; + sTransitionData->counter++; DestroySprite(sprite); } } } } +#undef sFade +#undef sFinished +#undef sDestroyAttempts +#undef sDelay +#undef sIsMainSprite + +//--------------------------- +// B_TRANSITION_GRID_SQUARES +//--------------------------- + +#define tDelay data[1] +#define tShrinkStage data[2] + static void Task_GridSquares(u8 taskId) { while (sGridSquares_Funcs[gTasks[taskId].tState](&gTasks[taskId])); @@ -3496,37 +3724,37 @@ static bool8 GridSquares_Init(struct Task *task) GetBg0TilesDst(&tilemap, &tileset); CpuSet(sShrinkingBoxTileset, tileset, 16); - CpuFill16(0xF000, tilemap, BG_SCREEN_SIZE); + CpuFill16(0xF0 << 8, tilemap, BG_SCREEN_SIZE); LoadPalette(sFieldEffectPal_Pokeball, 0xF0, sizeof(sFieldEffectPal_Pokeball)); task->tState++; return FALSE; } -static bool8 GridSquares_Func2(struct Task *task) +static bool8 GridSquares_Main(struct Task *task) { u16* tileset; - if (task->data[1] == 0) + if (task->tDelay == 0) { GetBg0TilemapDst(&tileset); - task->data[1] = 3; - task->data[2]++; - CpuSet(sShrinkingBoxTileset + (task->data[2] * 8), tileset, 16); - if (task->data[2] > 13) + task->tDelay = 3; + task->tShrinkStage++; + CpuSet(&sShrinkingBoxTileset[task->tShrinkStage * 8], tileset, 16); + if (task->tShrinkStage > 13) { task->tState++; - task->data[1] = 16; + task->tDelay = 16; } } - task->data[1]--; + task->tDelay--; return FALSE; } static bool8 GridSquares_End(struct Task *task) { - if (--task->data[1] == 0) + if (--task->tDelay == 0) { FadeScreenBlack(); DestroyTask(FindTaskIdByFunc(Task_GridSquares)); @@ -3534,12 +3762,23 @@ static bool8 GridSquares_End(struct Task *task) return FALSE; } -static void Task_Shards(u8 taskId) +#undef tDelay +#undef tShrinkStage + +//--------------------------- +// B_TRANSITION_ANGLED_WIPES +//--------------------------- + +#define tWipeId data[1] +#define tDir data[2] +#define tDelay data[3] + +static void Task_AngledWipes(u8 taskId) { - while (sShards_Funcs[gTasks[taskId].tState](&gTasks[taskId])); + while (sAngledWipes_Funcs[gTasks[taskId].tState](&gTasks[taskId])); } -static bool8 Shards_Init(struct Task *task) +static bool8 AngledWipes_Init(struct Task *task) { u16 i; @@ -3554,85 +3793,89 @@ static bool8 Shards_Init(struct Task *task) gScanlineEffectRegBuffers[0][i] = DISPLAY_WIDTH; CpuSet(gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], DISPLAY_HEIGHT); - SetVBlankCallback(VBlankCB_Shards); + SetVBlankCallback(VBlankCB_AngledWipes); task->tState++; return TRUE; } -static bool8 Shards_Func2(struct Task *task) +static bool8 AngledWipes_SetWipeData(struct Task *task) { - sub_814A1AC(sTransitionData->data, - sUnknown_085C8DD0[task->data[1]][0], - sUnknown_085C8DD0[task->data[1]][1], - sUnknown_085C8DD0[task->data[1]][2], - sUnknown_085C8DD0[task->data[1]][3], - 1, 1); - task->data[2] = sUnknown_085C8DD0[task->data[1]][4]; + InitBlackWipe(sTransitionData->data, + sAngledWipes_MoveData[task->tWipeId][0], + sAngledWipes_MoveData[task->tWipeId][1], + sAngledWipes_MoveData[task->tWipeId][2], + sAngledWipes_MoveData[task->tWipeId][3], + 1, 1); + task->tDir = sAngledWipes_MoveData[task->tWipeId][4]; task->tState++; return TRUE; } -static bool8 Shards_Func3(struct Task *task) +static bool8 AngledWipes_DoWipe(struct Task *task) { s16 i; - bool8 nextFunc; + bool8 finished; sTransitionData->VBlank_DMA = 0; - for (i = 0, nextFunc = FALSE; i < 16; i++) + for (i = 0, finished = FALSE; i < 16; i++) { - s16 r3 = gScanlineEffectRegBuffers[0][sTransitionData->data[3]] >> 8; - s16 r4 = gScanlineEffectRegBuffers[0][sTransitionData->data[3]] & 0xFF; - if (task->data[2] == 0) + s16 r3 = gScanlineEffectRegBuffers[0][sTransitionData->tWipeCurrY] >> 8; + s16 r4 = gScanlineEffectRegBuffers[0][sTransitionData->tWipeCurrY] & 0xFF; + if (task->tDir == 0) { - if (r3 < sTransitionData->data[2]) - r3 = sTransitionData->data[2]; + // Moving down + if (r3 < sTransitionData->tWipeCurrX) + r3 = sTransitionData->tWipeCurrX; if (r3 > r4) r3 = r4; } else { - if (r4 > sTransitionData->data[2]) - r4 = sTransitionData->data[2]; + // Moving up + if (r4 > sTransitionData->tWipeCurrX) + r4 = sTransitionData->tWipeCurrX; if (r4 <= r3) r4 = r3; } - gScanlineEffectRegBuffers[0][sTransitionData->data[3]] = (r4) | (r3 << 8); - if (nextFunc) + gScanlineEffectRegBuffers[0][sTransitionData->tWipeCurrY] = (r4) | (r3 << 8); + if (finished) { task->tState++; break; } - else - nextFunc = sub_814A228(sTransitionData->data, 1, 1); + finished = UpdateBlackWipe(sTransitionData->data, TRUE, TRUE); } sTransitionData->VBlank_DMA++; return FALSE; } -static bool8 Shards_Func4(struct Task *task) +static bool8 AngledWipes_TryEnd(struct Task *task) { - if (++task->data[1] < 7) + if (++task->tWipeId < NUM_ANGLED_WIPES) { + // Continue with next wipe task->tState++; - task->data[3] = sUnknown_085C8E16[task->data[1] - 1]; + task->tDelay = sAngledWipes_EndDelays[task->tWipeId - 1]; return TRUE; } else { + // End transition DmaStop(0); FadeScreenBlack(); - DestroyTask(FindTaskIdByFunc(Task_Shards)); + DestroyTask(FindTaskIdByFunc(Task_AngledWipes)); return FALSE; } } -static bool8 Shards_Func5(struct Task *task) +static bool8 AngledWipes_StartNext(struct Task *task) { - if (--task->data[3] == 0) + if (--task->tDelay == 0) { + // Return to AngledWipes_SetWipeData task->tState = 1; return TRUE; } @@ -3640,7 +3883,7 @@ static bool8 Shards_Func5(struct Task *task) return FALSE; } -static void VBlankCB_Shards(void) +static void VBlankCB_AngledWipes(void) { DmaStop(0); VBlankCB_BattleTransition(); @@ -3653,20 +3896,31 @@ static void VBlankCB_Shards(void) DmaSet(0, gScanlineEffectRegBuffers[1], ®_WIN0H, B_TRANS_DMA_FLAGS); } -#undef tFuncState -#undef tOpponentSpriteId -#undef tPlayerSpriteId -#undef tMugshotId +#undef tWipeId +#undef tDir +#undef tDelay -static void CreateIntroTask(s16 a0, s16 a1, s16 a2, s16 a3, s16 a4) +//----------------------------------- +// Transition intro +//----------------------------------- + +#define tFadeToGrayDelay data[1] +#define tFadeFromGrayDelay data[2] +#define tNumFades data[3] +#define tFadeToGrayIncrement data[4] +#define tFadeFromGrayIncrement data[5] +#define tDelayTimer data[6] +#define tBlend data[7] + +static void CreateIntroTask(s16 fadeToGrayDelay, s16 fadeFromGrayDelay, s16 numFades, s16 fadeToGrayIncrement, s16 fadeFromGrayIncrement) { u8 taskId = CreateTask(Task_BattleTransition_Intro, 3); - gTasks[taskId].data[1] = a0; - gTasks[taskId].data[2] = a1; - gTasks[taskId].data[3] = a2; - gTasks[taskId].data[4] = a3; - gTasks[taskId].data[5] = a4; - gTasks[taskId].data[6] = a0; + gTasks[taskId].tFadeToGrayDelay = fadeToGrayDelay; + gTasks[taskId].tFadeFromGrayDelay = fadeFromGrayDelay; + gTasks[taskId].tNumFades = numFades; + gTasks[taskId].tFadeToGrayIncrement = fadeToGrayIncrement; + gTasks[taskId].tFadeFromGrayIncrement = fadeFromGrayIncrement; + gTasks[taskId].tDelayTimer = fadeToGrayDelay; } static bool8 IsIntroTaskDone(void) @@ -3682,47 +3936,64 @@ void Task_BattleTransition_Intro(u8 taskId) while (sTransitionIntroFuncs[gTasks[taskId].tState](&gTasks[taskId])); } -static bool8 Transition_Intro_1(struct Task *task) +static bool8 TransitionIntro_FadeToGray(struct Task *task) { - if (task->data[6] == 0 || --task->data[6] == 0) + if (task->tDelayTimer == 0 || --task->tDelayTimer == 0) { - task->data[6] = task->data[1]; - task->data[7] += task->data[4]; - if (task->data[7] > 16) - task->data[7] = 16; - BlendPalettes(PALETTES_ALL, task->data[7], RGB(11, 11, 11)); + task->tDelayTimer = task->tFadeToGrayDelay; + task->tBlend += task->tFadeToGrayIncrement; + if (task->tBlend > 16) + task->tBlend = 16; + BlendPalettes(PALETTES_ALL, task->tBlend, RGB(11, 11, 11)); } - if (task->data[7] > 15) + if (task->tBlend >= 16) { + // Fade to gray complete, start fade back task->tState++; - task->data[6] = task->data[2]; + task->tDelayTimer = task->tFadeFromGrayDelay; } return FALSE; } -static bool8 Transition_Intro_2(struct Task *task) +static bool8 TransitionIntro_FadeFromGray(struct Task *task) { - if (task->data[6] == 0 || --task->data[6] == 0) + if (task->tDelayTimer == 0 || --task->tDelayTimer == 0) { - task->data[6] = task->data[2]; - task->data[7] -= task->data[5]; - if (task->data[7] < 0) - task->data[7] = 0; - BlendPalettes(PALETTES_ALL, task->data[7], RGB(11, 11, 11)); + task->tDelayTimer = task->tFadeFromGrayDelay; + task->tBlend -= task->tFadeFromGrayIncrement; + if (task->tBlend < 0) + task->tBlend = 0; + BlendPalettes(PALETTES_ALL, task->tBlend, RGB(11, 11, 11)); } - if (task->data[7] == 0) + if (task->tBlend == 0) { - if (--task->data[3] == 0) + if (--task->tNumFades == 0) + { + // All fades done, end intro DestroyTask(FindTaskIdByFunc(Task_BattleTransition_Intro)); + } else { - task->data[6] = task->data[1]; + // Fade from gray complete, start new fade + task->tDelayTimer = task->tFadeToGrayDelay; task->tState = 0; } } return FALSE; } +#undef tFadeToGrayDelay +#undef tFadeFromGrayDelay +#undef tNumFades +#undef tFadeToGrayIncrement +#undef tFadeFromGrayIncrement +#undef tDelayTimer +#undef tBlend + +//----------------------------------- +// General transition functions +//----------------------------------- + static void InitTransitionData(void) { memset(sTransitionData, 0, sizeof(*sTransitionData)); @@ -3740,7 +4011,7 @@ static void GetBg0TilemapDst(u16 **tileset) { u16 charBase = REG_BG0CNT >> 2; charBase <<= 14; - *tileset = (u16*)(VRAM + charBase); + *tileset = (u16*)(BG_VRAM + charBase); } void GetBg0TilesDst(u16 **tilemap, u16 **tileset) @@ -3751,8 +4022,8 @@ void GetBg0TilesDst(u16 **tilemap, u16 **tileset) screenBase <<= 11; charBase <<= 14; - *tilemap = (u16*)(VRAM + screenBase); - *tileset = (u16*)(VRAM + charBase); + *tilemap = (u16*)(BG_VRAM + screenBase); + *tileset = (u16*)(BG_VRAM + charBase); } static void FadeScreenBlack(void) @@ -3767,126 +4038,151 @@ static void SetSinWave(s16 *array, s16 sinAdd, s16 index, s16 indexIncrementer, array[i] = sinAdd + Sin(index & 0xFF, amplitude); } -static void sub_814A014(u16 *array, s16 x, s16 y, s16 amplitude) +static void SetCircularMask(u16 *buffer, s16 centerX, s16 centerY, s16 radius) { s16 i; - memset(array, 10, DISPLAY_HEIGHT * sizeof(s16)); + memset(buffer, 10, DISPLAY_HEIGHT * sizeof(u16)); for (i = 0; i < 64; i++) { s16 sinResult, cosResult; - s16 toStoreOrr, r2, r3, toStore, r7, r8; + s16 drawXLeft, drawYBottNext, drawYTopNext, drawX, drawYTop, drawYBott; - sinResult = Sin(i, amplitude); - cosResult = Cos(i, amplitude); + sinResult = Sin(i, radius); + cosResult = Cos(i, radius); - toStoreOrr = x - sinResult; - toStore = x + sinResult; - r7 = y - cosResult; - r8 = y + cosResult; + drawXLeft = centerX - sinResult; + drawX = centerX + sinResult; + drawYTop = centerY - cosResult; + drawYBott = centerY + cosResult; - if (toStoreOrr < 0) - toStoreOrr = 0; - if (toStore > DISPLAY_WIDTH) - toStore = DISPLAY_WIDTH; - if (r7 < 0) - r7 = 0; - if (r8 > DISPLAY_HEIGHT - 1) - r8 = DISPLAY_HEIGHT - 1; + if (drawXLeft < 0) + drawXLeft = 0; + if (drawX > DISPLAY_WIDTH) + drawX = DISPLAY_WIDTH; + if (drawYTop < 0) + drawYTop = 0; + if (drawYBott > DISPLAY_HEIGHT - 1) + drawYBott = DISPLAY_HEIGHT - 1; - toStore |= (toStoreOrr << 8); - array[r7] = toStore; - array[r8] = toStore; + drawX |= (drawXLeft << 8); + buffer[drawYTop] = drawX; + buffer[drawYBott] = drawX; - cosResult = Cos(i + 1, amplitude); - r3 = y - cosResult; - r2 = y + cosResult; + cosResult = Cos(i + 1, radius); + drawYTopNext = centerY - cosResult; + drawYBottNext = centerY + cosResult; - if (r3 < 0) - r3 = 0; - if (r2 > DISPLAY_HEIGHT - 1) - r2 = DISPLAY_HEIGHT - 1; + if (drawYTopNext < 0) + drawYTopNext = 0; + if (drawYBottNext > DISPLAY_HEIGHT - 1) + drawYBottNext = DISPLAY_HEIGHT - 1; - while (r7 > r3) - array[--r7] = toStore; - while (r7 < r3) - array[++r7] = toStore; + while (drawYTop > drawYTopNext) + buffer[--drawYTop] = drawX; + while (drawYTop < drawYTopNext) + buffer[++drawYTop] = drawX; - while (r8 > r2) - array[--r8] = toStore; - while (r8 < r2) - array[++r8] = toStore; + while (drawYBott > drawYBottNext) + buffer[--drawYBott] = drawX; + while (drawYBott < drawYBottNext) + buffer[++drawYBott] = drawX; } } -static void sub_814A1AC(s16 *data, s16 a1, s16 a2, s16 a3, s16 a4, s16 a5, s16 a6) +static void InitBlackWipe(s16 *data, s16 startX, s16 startY, s16 endX, s16 endY, s16 xMove, s16 yMove) { - data[0] = a1; - data[1] = a2; - data[2] = a1; - data[3] = a2; - data[4] = a3; - data[5] = a4; - data[6] = a5; - data[7] = a6; - data[8] = a3 - a1; - if (data[8] < 0) + tWipeStartX = startX; + tWipeStartY = startY; + tWipeCurrX = startX; + tWipeCurrY = startY; + tWipeEndX = endX; + tWipeEndY = endY; + tWipeXMove = xMove; + tWipeYMove = yMove; + tWipeXDist = endX - startX; + if (tWipeXDist < 0) { - data[8] = -data[8]; - data[6] = -a5; + // If end was less than start, reverse direction + tWipeXDist = -tWipeXDist; + tWipeXMove = -xMove; } - data[9] = a4 - a2; - if (data[9] < 0) + tWipeYDist = endY - startY; + if (tWipeYDist < 0) { - data[9] = -data[9]; - data[7] = -a6; + // If end was less than start, reverse direction + tWipeYDist = -tWipeYDist; + tWipeYMove = -yMove; } - data[10] = 0; + tWipeTemp = 0; } -static bool8 sub_814A228(s16 *data, bool8 a1, bool8 a2) +static bool8 UpdateBlackWipe(s16 *data, bool8 xExact, bool8 yExact) { - u8 var; - if (data[8] > data[9]) + u8 numFinished; + + if (tWipeXDist > tWipeYDist) { - data[2] += data[6]; - data[10] += data[9]; - if (data[10] > data[8]) + // X has further to move, move it first + tWipeCurrX += tWipeXMove; + + // If it has been far enough since Y's + // last move then move it too + tWipeTemp += tWipeYDist; + if (tWipeTemp > tWipeXDist) { - data[3] += data[7]; - data[10] -= data[8]; + tWipeCurrY += tWipeYMove; + tWipeTemp -= tWipeXDist; } } else { - data[3] += data[7]; - data[10] += data[8]; - if (data[10] > data[9]) + // Y has further to move, move it first + tWipeCurrY += tWipeYMove; + + // If it has been far enough since X's + // last move then move it too + tWipeTemp += tWipeXDist; + if (tWipeTemp > tWipeYDist) { - data[2] += data[6]; - data[10] -= data[9]; + tWipeCurrX += tWipeXMove; + tWipeTemp -= tWipeYDist; } } - var = 0; - if ((data[6] > 0 && data[2] >= data[4]) || (data[6] < 0 && data[2] <= data[4])) + + numFinished = 0; + + // Has X coord reached end? + if ((tWipeXMove > 0 && tWipeCurrX >= tWipeEndX) + || (tWipeXMove < 0 && tWipeCurrX <= tWipeEndX)) { - var++; - if (a1) - data[2] = data[4]; - } - if ((data[7] > 0 && data[3] >= data[5]) || (data[7] < 0 && data[3] <= data[5])) - { - var++; - if (a2) - data[3] = data[5]; + numFinished++; + if (xExact) + tWipeCurrX = tWipeEndX; } - if (var == 2) + // Has Y coord reached end? + if ((tWipeYMove > 0 && tWipeCurrY >= tWipeEndY) + || (tWipeYMove < 0 && tWipeCurrY <= tWipeEndY)) + { + numFinished++; + if (yExact) + tWipeCurrY = tWipeEndY; + } + + // Return TRUE if both coords have reached end + if (numFinished == 2) return TRUE; else return FALSE; } +//----------------------------------- +// B_TRANSITION_FRONTIER_LOGO_WIGGLE +//----------------------------------- + +#define tAmplitude data[5] + static bool8 FrontierLogoWiggle_Init(struct Task *task) { u16 *tilemap, *tileset; @@ -3907,7 +4203,7 @@ static bool8 FrontierLogoWiggle_SetGfx(struct Task *task) GetBg0TilesDst(&tilemap, &tileset); LZ77UnCompVram(sFrontierLogo_Tilemap, tilemap); - SetSinWave(gScanlineEffectRegBuffers[0], 0, task->data[4], 0x84, task->data[5], DISPLAY_HEIGHT); + SetSinWave(gScanlineEffectRegBuffers[0], 0, task->data[4], 0x84, task->tAmplitude, DISPLAY_HEIGHT); task->tState++; return TRUE; @@ -3918,6 +4214,20 @@ static void Task_FrontierLogoWiggle(u8 taskId) while (sFrontierLogoWiggle_Funcs[gTasks[taskId].tState](&gTasks[taskId])); } +#undef tAmplitude + +//--------------------------------- +// B_TRANSITION_FRONTIER_LOGO_WAVE +//--------------------------------- + +#define tSinVal data[1] +#define tAmplitudeVal data[2] +#define tTimer data[3] +#define tStartedFade data[4] +#define tBlendTarget2 data[5] +#define tBlendTarget1 data[6] +#define tSinDecrement data[7] + static void Task_FrontierLogoWave(u8 taskId) { while (sFrontierLogoWave_Funcs[gTasks[taskId].tState](&gTasks[taskId])); @@ -3930,13 +4240,13 @@ static bool8 FrontierLogoWave_Init(struct Task *task) InitTransitionData(); ScanlineEffect_Clear(); ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON | DISPCNT_WIN1_ON); - task->data[2] = 0x2000; - task->data[1] = 0x7FFF; - task->data[5] = 0; - task->data[6] = 16; - task->data[7] = 2560; + task->tAmplitudeVal = 32 << 8; + task->tSinVal = 0x7FFF; + task->tBlendTarget2 = 0; + task->tBlendTarget1 = 16; + task->tSinDecrement = 2560; sTransitionData->BLDCNT = BLDCNT_TGT1_BG0 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL; - sTransitionData->BLDALPHA = BLDALPHA_BLEND(task->data[5], task->data[6]); + sTransitionData->BLDALPHA = BLDALPHA_BLEND(task->tBlendTarget2, task->tBlendTarget1); REG_BLDCNT = sTransitionData->BLDCNT; REG_BLDALPHA = sTransitionData->BLDALPHA; GetBg0TilesDst(&tilemap, &tileset); @@ -3978,50 +4288,54 @@ static bool8 FrontierLogoWave_Func3(struct Task *task) static bool8 FrontierLogoWave_Func4(struct Task *task) { u8 i; - u16 var6, amplitude, var8; + u16 sinVal, amplitude, sinSpread; sTransitionData->VBlank_DMA = FALSE; - amplitude = task->data[2] >> 8; - var6 = task->data[1]; - var8 = 384; + amplitude = task->tAmplitudeVal >> 8; + sinVal = task->tSinVal; + sinSpread = 384; - task->data[1] = var6 - task->data[7]; + task->tSinVal -= task->tSinDecrement; - if (task->data[3] >= 70) + if (task->tTimer >= 70) { - if (task->data[2] - 384 >= 0) - task->data[2] -= 384; + // Decrease amount logo moves up and down + // until it rests in the middle of the screen. + if (task->tAmplitudeVal - 384 >= 0) + task->tAmplitudeVal -= 384; else - task->data[2] = 0; + task->tAmplitudeVal = 0; } - if (task->data[3] >= 0 && task->data[3] % 3 == 0) + if (task->tTimer >= 0 && task->tTimer % 3 == 0) { - if (task->data[5] < 16) - task->data[5]++; - else if (task->data[6] > 0) - task->data[6]--; + // Blend logo into view + if (task->tBlendTarget2 < 16) + task->tBlendTarget2++; + else if (task->tBlendTarget1 > 0) + task->tBlendTarget1--; - sTransitionData->BLDALPHA = BLDALPHA_BLEND(task->data[5], task->data[6]); + sTransitionData->BLDALPHA = BLDALPHA_BLEND(task->tBlendTarget2, task->tBlendTarget1); } - for (i = 0; i < DISPLAY_HEIGHT; i++, var6 += var8) + // Move logo up and down + for (i = 0; i < DISPLAY_HEIGHT; i++, sinVal += sinSpread) { - s16 index = var6 / 256; + s16 index = sinVal / 256; gScanlineEffectRegBuffers[0][i] = sTransitionData->cameraY + Sin(index & 0xff, amplitude); } - if (++task->data[3] == 101) + if (++task->tTimer == 101) { - task->data[4]++; + task->tStartedFade++; BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK); } - if (task->data[4] != 0 && !gPaletteFade.active) + if (task->tStartedFade && !gPaletteFade.active) DestroyTask(FindTaskIdByFunc(Task_FrontierLogoWave)); - task->data[7] -= 17; + task->tSinDecrement -= 17; sTransitionData->VBlank_DMA++; return FALSE; } @@ -4042,6 +4356,30 @@ static void HBlankCB_FrontierLogoWave(void) REG_BG0VOFS = var; } +#undef tSinVal +#undef tAmplitudeVal +#undef tTimer +#undef tStartedFade +#undef tBlendTarget2 +#undef tBlendTarget1 +#undef tSinDecrement + +//---------------------------------------------------------------------- +// B_TRANSITION_FRONTIER_SQUARES, B_TRANSITION_FRONTIER_SQUARES_SCROLL, +// and B_TRANSITION_FRONTIER_SQUARES_SPIRAL +//---------------------------------------------------------------------- + +#define NUM_SQUARES_PER_ROW 7 +#define NUM_SQUARES_PER_COL 5 +#define SQUARE_SIZE 4 + +#define tPosX data[2] +#define tPosY data[3] +#define tRowPos data[4] +#define tShrinkState data[5] +#define tShrinkDelayTimer data[6] +#define tShrinkDelay data[7] + static void Task_FrontierSquares(u8 taskId) { while (sFrontierSquares_Funcs[gTasks[taskId].tState](&gTasks[taskId])); @@ -4070,42 +4408,46 @@ static bool8 FrontierSquares_Init(struct Task *task) CopyBgTilemapBufferToVram(0); LoadPalette(sFrontierSquares_Palette, 0xF0, sizeof(sFrontierSquares_Palette)); - task->data[2] = 1; - task->data[3] = 0; - task->data[4] = 0; - task->data[7] = 10; + task->tPosX = 1; + task->tPosY = 0; + task->tRowPos = 0; + task->tShrinkDelay = 10; task->tState++; return FALSE; } -static bool8 FrontierSquares_Func2(struct Task *task) +static bool8 FrontierSquares_Draw(struct Task *task) { - CopyRectToBgTilemapBufferRect(0, sFrontierSquares_Tilemap, 0, 0, 4, 4, task->data[2], task->data[3], 4, 4, 0xF, 0, 0); + CopyRectToBgTilemapBufferRect(0, sFrontierSquares_Tilemap, 0, 0, + SQUARE_SIZE, SQUARE_SIZE, + task->tPosX, task->tPosY, + SQUARE_SIZE, SQUARE_SIZE, + 15, 0, 0); CopyBgTilemapBufferToVram(0); - task->data[2] += 4; - if (++task->data[4] == 7) + task->tPosX += SQUARE_SIZE; + if (++task->tRowPos == NUM_SQUARES_PER_ROW) { - task->data[2] = 1; - task->data[3] += 4; - task->data[4] = 0; - if (task->data[3] > 19) + task->tPosX = 1; + task->tPosY += SQUARE_SIZE; + task->tRowPos = 0; + if (task->tPosY >= NUM_SQUARES_PER_COL * SQUARE_SIZE) task->tState++; } return FALSE; } -static bool8 FrontierSquares_Func3(struct Task *task) +static bool8 FrontierSquares_Shrink(struct Task *task) { u8 i; u16 *tilemap, *tileset; GetBg0TilesDst(&tilemap, &tileset); - if (task->data[6]++ >= task->data[7]) + if (task->tShrinkDelayTimer++ >= task->tShrinkDelay) { - switch (task->data[5]) + switch (task->tShrinkState) { case 0: for (i = 250; i < 255; i++) @@ -4131,13 +4473,20 @@ static bool8 FrontierSquares_Func3(struct Task *task) return FALSE; } - task->data[6] = 0; - task->data[5]++; + task->tShrinkDelayTimer = 0; + task->tShrinkState++; } return FALSE; } +#undef tPosX +#undef tPosY +#undef tRowPos +#undef tShrinkState +#undef tShrinkDelayTimer +#undef tShrinkDelay + static bool8 FrontierSquaresSpiral_Init(struct Task *task) { u16 *tilemap, *tileset;