mirror of
https://github.com/pret/pokefirered.git
synced 2026-05-06 05:35:23 -05:00
3726 lines
111 KiB
C
3726 lines
111 KiB
C
#include "global.h"
|
|
#include "sprite.h"
|
|
#include "task.h"
|
|
#include "overworld.h"
|
|
#include "malloc.h"
|
|
#include "palette.h"
|
|
#include "trig.h"
|
|
#include "random.h"
|
|
#include "sound.h"
|
|
#include "decompress.h"
|
|
#include "gpu_regs.h"
|
|
#include "battle_transition.h"
|
|
#include "field_effect.h"
|
|
#include "field_weather.h"
|
|
#include "field_camera.h"
|
|
#include "trainer_pokemon_sprites.h"
|
|
#include "scanline_effect.h"
|
|
#include "constants/songs.h"
|
|
|
|
typedef bool8 (*TransitionStateFunc)(struct Task *task);
|
|
typedef bool8 (*TransitionSpriteCallback)(struct Sprite *sprite);
|
|
|
|
struct TransitionData
|
|
{
|
|
vu8 vblankDma;
|
|
u16 winIn;
|
|
u16 winOut;
|
|
u16 win0H;
|
|
u16 win0V;
|
|
u16 unused_A;
|
|
u16 win1V;
|
|
u16 bldCnt;
|
|
u16 bldAlpha;
|
|
u16 bldY;
|
|
s16 bg123HOfs;
|
|
s16 bg123VOfs;
|
|
s16 bg0HOfsOpponent;
|
|
s16 bg0HOfsPlayer;
|
|
s16 bg0VOfs;
|
|
s16 unused_1E;
|
|
s16 counter;
|
|
s16 unused_22;
|
|
s16 data[11]; // for multiple purposes
|
|
};
|
|
|
|
static EWRAM_DATA struct TransitionData *sTransitionStructPtr = NULL;
|
|
|
|
// TODO: Move this declaration to include/event_object_movement.h
|
|
extern const struct OamData gEventObjectBaseOam_32x32;
|
|
|
|
static bool8 BT_Phase1_FadeOut(struct Task *task);
|
|
static bool8 BT_Phase1_FadeIn(struct Task *task);
|
|
static bool8 BT_Phase2BlackDoodles_Init(struct Task *task);
|
|
static bool8 BT_Phase2BlackDoodles_InitSingleBrush(struct Task *task);
|
|
static bool8 BT_Phase2BlackDoodles_DrawSingleBrush(struct Task *task);
|
|
static bool8 BT_Phase2BlackDoodles_IsDone(struct Task *task);
|
|
static bool8 BT_Phase2BlackDoodles_NextBrush(struct Task *task);
|
|
static bool8 BT_Phase2GridSquares_LoadGfx(struct Task *task);
|
|
static bool8 BT_Phase2GridSquares_UpdateTileset(struct Task *task);
|
|
static bool8 BT_Phase2GridSquares_IsDone(struct Task *task);
|
|
static bool8 BT_Phase2WhiteFadeInStripes_Init(struct Task *task);
|
|
static bool8 BT_Phase2WhiteFadeInStripes_SetupSprites(struct Task *task);
|
|
static bool8 BT_Phase2WhiteFadeInStripes_IsWhiteFadeDone(struct Task *task);
|
|
static bool8 BT_Phase2WhiteFadeInStripes_Stop(struct Task *task);
|
|
static bool8 BT_Phase2WhiteFadeInStripes_IsDone(struct Task *task);
|
|
static bool8 BT_Phase2SlicedScreen_Init(struct Task *task);
|
|
static bool8 BT_Phase2SlicedScreen_UpdateOffsets(struct Task *task);
|
|
static bool8 BT_Phase2SlicedScreen_End(struct Task *task);
|
|
static bool8 BT_Phase2Mugshot_Init(struct Task *task);
|
|
static bool8 BT_Phase2Mugshot_LoadGfx(struct Task *task);
|
|
static bool8 BT_Phase2Mugshot_VsBarsSlideIn(struct Task *task);
|
|
static bool8 BT_Phase2Mugshot_StartSpriteSlide(struct Task *task);
|
|
static bool8 BT_Phase2Mugshot_WaitForOpponentInPlace(struct Task *task);
|
|
static bool8 BT_Phase2Mugshot_WaitForPlayerInPlace(struct Task *task);
|
|
static bool8 BT_Phase2Mugshot_ExpandWhiteBand(struct Task *task);
|
|
static bool8 BT_Phase2Mugshot_StartBlackFade(struct Task *task);
|
|
static bool8 BT_Phase2Mugshot_WaitForBlackFade(struct Task *task);
|
|
static bool8 BT_Phase2Mugshot_End(struct Task *task);
|
|
static bool8 BT_Phase2AntiClockwiseSpiral_Init(struct Task *task);
|
|
static bool8 BT_Phase2AntiClockwiseSpiral_Update(struct Task *task);
|
|
static bool8 BT_Phase2BlackWaveToRight_Init(struct Task *task);
|
|
static bool8 BT_Phase2BlackWaveToRight_UpdateWave(struct Task *task);
|
|
static bool8 BT_Phase2BlackWaveToRight_End(struct Task *task);
|
|
static bool8 BT_Phase2FullScreenWave_Init(struct Task *task);
|
|
static bool8 BT_Phase2FullScreenWave_UpdateWave(struct Task *task);
|
|
static bool8 BT_Phase2ClockwiseBlackFade_Init(struct Task *task);
|
|
static bool8 BT_Phase2ClockwiseBlackFade_Step1(struct Task *task);
|
|
static bool8 BT_Phase2ClockwiseBlackFade_Step2(struct Task *task);
|
|
static bool8 BT_Phase2ClockwiseBlackFade_Step3(struct Task *task);
|
|
static bool8 BT_Phase2ClockwiseBlackFade_Step4(struct Task *task);
|
|
static bool8 BT_Phase2ClockwiseBlackFade_Step5(struct Task *task);
|
|
static bool8 BT_Phase2ClockwiseBlackFade_End(struct Task *task);
|
|
static bool8 BT_Phase2SlidingPokeballs_LoadBgGfx(struct Task *task);
|
|
static bool8 BT_Phase2SlidingPokeballs_SetupFldeffArgs(struct Task *task);
|
|
static bool8 BT_Phase2SlidingPokeballs_IsDone(struct Task *task);
|
|
static bool8 BT_Phase2BigPokeball_Init(struct Task *task);
|
|
static bool8 BT_Phase2BigPokeball_LoadTilemapAndWave(struct Task *task);
|
|
static bool8 BT_Phase2BigPokeball_UpdateWave1IncEva(struct Task *task);
|
|
static bool8 BT_Phase2BigPokeball_UpdateWave2DecEvb(struct Task *task);
|
|
static bool8 BT_Phase2BigPokeball_UpdateWave3(struct Task *task);
|
|
static bool8 BT_Phase2BigPokeball_CircleEffect(struct Task *task);
|
|
static bool8 BT_Phase2HorizontalCorrugate_Init(struct Task *task);
|
|
static bool8 BT_Phase2HorizontalCorrugate_UpdateWave(struct Task *task);
|
|
static bool8 BT_Phase2DistortedWave_InitWave(struct Task *task);
|
|
static bool8 BT_Phase2DistortedWave_UpdateWave(struct Task *task);
|
|
static bool8 BT_Phase2Blur_InitBgMosaic(struct Task *task);
|
|
static bool8 BT_Phase2Blur_Anim(struct Task *task);
|
|
static bool8 BT_Phase2Blur_IsDone(struct Task *task);
|
|
static bool8 BT_Phase1Blink(struct Task *task);
|
|
static bool8 BT_WaitForPhase1(struct Task *task);
|
|
static bool8 BT_Phase2LaunchAnimTask(struct Task *task);
|
|
static bool8 BT_WaitForPhase2(struct Task *task);
|
|
|
|
static void BT_Phase2Blur(u8 taskId);
|
|
static void BT_Phase2DistortedWave(u8 taskId);
|
|
static void BT_Phase2HorizontalCorrugate(u8 taskId);
|
|
static void BT_Phase2BigPokeball(u8 taskId);
|
|
static void BT_Phase2SlidingPokeballs(u8 taskId);
|
|
static void BT_Phase2ClockwiseBlackFade(u8 taskId);
|
|
static void BT_Phase2FullScreenWave(u8 taskId);
|
|
static void BT_Phase2BlackWaveToRight(u8 taskId);
|
|
static void BT_Phase2SlicedScreen(u8 taskId);
|
|
static void BT_Phase2WhiteFadeInStripes(u8 taskId);
|
|
static void BT_Phase2GridSquares(u8 taskId);
|
|
static void BT_Phase2BlackDoodles(u8 taskId);
|
|
static void BT_Phase2StartLoreleiMugshot(u8 taskId);
|
|
static void BT_Phase2StartBrunoMugshot(u8 taskId);
|
|
static void BT_Phase2StartAgathaMugshot(u8 taskId);
|
|
static void BT_Phase2StartLanceMugshot(u8 taskId);
|
|
static void BT_Phase2StartBlueMugshot(u8 taskId);
|
|
static void BT_Phase2AntiClockwiseSpiral(u8 taskId);
|
|
static void BT_Phase1Task(u8 taskId);
|
|
static void BT_Phase2Mugshot(u8 taskId);
|
|
static void BT_Phase1SubTask(u8 taskId);
|
|
|
|
static void SpriteCB_BT_Phase2Mugshots(struct Sprite *sprite);
|
|
static void SpriteCB_BT_Phase2SlidingPokeballs(struct Sprite *sprite);
|
|
static void SpriteCB_BT_Phase2WhiteFadeInStripes(struct Sprite *sprite);
|
|
|
|
static bool8 BT_Phase2MugshotsSpriteFuncs_Wait(struct Sprite *sprite);
|
|
static bool8 BT_Phase2MugshotsSpriteFuncs_InitParams(struct Sprite *sprite);
|
|
static bool8 BT_Phase2MugshotsSpriteFuncs_SlideSpriteIn(struct Sprite *sprite);
|
|
static bool8 BT_Phase2MugshotsSpriteFuncs_DecelerateSprite(struct Sprite *sprite);
|
|
static bool8 BT_Phase2MugshotsSpriteFuncs_DecelerateSprite2(struct Sprite *sprite);
|
|
|
|
static void VBCB_BT_Phase2DistortedWave(void);
|
|
static void HBCB_BT_Phase2DistortedWave(void);
|
|
static void VBCB_BT_Phase2HorizontalCorrugate(void);
|
|
static void HBCB_BT_Phase2HorizontalCorrugate(void);
|
|
static void VBCB_BT_Phase2BigPokeball1(void);
|
|
static void VBCB_BT_Phase2BigPokeball2(void);
|
|
static void HBCB_BT_Phase2BigPokeball(void);
|
|
static void VBCB_BT_Phase2ClockwiseBlackFade(void);
|
|
static void VBCB_BT_Phase2FullScreenWave(void);
|
|
static void HBCB_BT_Phase2FullScreenWave(void);
|
|
static void VBCB_BT_Phase2BlackWaveToRight(void);
|
|
static void VBCB_BT_Phase2AntiClockwiseBlackFade(void);
|
|
static void VBCB_BT_Phase2Mugshot1_Slide(void);
|
|
static void VBCB_BT_Phase2Mugshot2_WhiteFade(void);
|
|
static void HBCB_BT_Phase2Mugshot(void);
|
|
static void VBCB_BT_Phase2SlicedScreen(void);
|
|
static void HBCB_BT_Phase2SlicedScreen(void);
|
|
static void VBCB_BT_Phase2WhiteFadeInStripes1(void);
|
|
static void VBCB_BT_Phase2WhiteFadeInStripes2(void);
|
|
static void HBCB_BT_Phase2WhiteFadeInStripes(void);
|
|
static void VBCB_BT_Phase2BlackDoodles(void);
|
|
|
|
static void BT_LaunchTask(u8 transitionId);
|
|
static void BT_TaskMain(u8 taskId);
|
|
static void BT_InitCtrlBlk(void);
|
|
static void BT_CreatePhase1SubTask(s16 fadeOutDelay, s16 fadeInDelay, s16 blinkTimes, s16 fadeOutSpeed, s16 fadeInSpeed);
|
|
static bool8 BT_IsPhase1Done(void);
|
|
static void BT_VBSyncOamAndPltt(void);
|
|
static void BT_GetBg0TilesetBase(u16 **tilesetPtr);
|
|
static void BT_GetBg0TilemapAndTilesetBase(u16 **tilemapPtr, u16 **tilesetPtr);
|
|
static void BT_LoadWaveIntoBuffer(s16 *buffer, s16 offset, s16 theta, s16 frequency, s16 amplitude, s16 bufSize);
|
|
static void BT_GenerateCircle(s16 *buffer, s16 x, s16 y, s16 radius);
|
|
static void BT_BlendPalettesToBlack(void);
|
|
static void BT_DiagonalSegment_InitParams(s16 *data, s16 startPtX, s16 startPtY, s16 endPtX, s16 endPtY, s16 stepX, s16 stepY);
|
|
static bool8 BT_DiagonalSegment_ComputePointOnSegment(s16 *data, bool8 checkBoundary1, bool8 checkBoundary2);
|
|
static void BT_SetSpriteAsOpponentOrPlayer(s16 spriteId, bool16 value);
|
|
static void BT_StartSpriteSlide(s16 spriteId);
|
|
static s16 BT_IsSpriteSlideFinished(s16 spriteId);
|
|
static void BT_Phase2Mugshots_CreateSprites(struct Task *task);
|
|
|
|
static const u32 sBigPokeballTileset[] = INCBIN_U32("graphics/battle_transitions/big_pokeball_tileset.4bpp");
|
|
static const u32 sSlidingPokeballTilemap[] = INCBIN_U32("graphics/battle_transitions/sliding_pokeball_tilemap.bin");
|
|
static const u8 sSpriteImage_SlidingPokeball[] = INCBIN_U8("graphics/battle_transitions/sliding_pokeball.4bpp");
|
|
static const u32 sVsBarTileset[] = INCBIN_U32("graphics/battle_transitions/vsbar_tileset.4bpp");
|
|
static const u8 sSpriteImage_UnusedBrendan[] = INCBIN_U8("graphics/battle_transitions/unused_brendan.4bpp");
|
|
static const u8 sSpriteImage_UnusedLass[] = INCBIN_U8("graphics/battle_transitions/unused_lass.4bpp");
|
|
static const u32 sGridSquareTileset[] = INCBIN_U32("graphics/battle_transitions/grid_square_tileset.4bpp");
|
|
|
|
static const TaskFunc sBT_Phase1Tasks[] =
|
|
{
|
|
BT_Phase1Task,
|
|
BT_Phase1Task,
|
|
BT_Phase1Task,
|
|
BT_Phase1Task,
|
|
BT_Phase1Task,
|
|
BT_Phase1Task,
|
|
BT_Phase1Task,
|
|
BT_Phase1Task,
|
|
BT_Phase1Task,
|
|
BT_Phase1Task,
|
|
BT_Phase1Task,
|
|
BT_Phase1Task,
|
|
BT_Phase1Task,
|
|
BT_Phase1Task,
|
|
BT_Phase1Task,
|
|
BT_Phase1Task,
|
|
BT_Phase1Task,
|
|
BT_Phase1Task,
|
|
};
|
|
|
|
static const TaskFunc sBT_Phase2Tasks[] =
|
|
{
|
|
BT_Phase2Blur,
|
|
BT_Phase2DistortedWave,
|
|
BT_Phase2HorizontalCorrugate,
|
|
BT_Phase2BigPokeball,
|
|
BT_Phase2SlidingPokeballs,
|
|
BT_Phase2ClockwiseBlackFade,
|
|
BT_Phase2FullScreenWave,
|
|
BT_Phase2BlackWaveToRight,
|
|
BT_Phase2SlicedScreen,
|
|
BT_Phase2WhiteFadeInStripes,
|
|
BT_Phase2GridSquares,
|
|
BT_Phase2BlackDoodles,
|
|
BT_Phase2StartLoreleiMugshot,
|
|
BT_Phase2StartBrunoMugshot,
|
|
BT_Phase2StartAgathaMugshot,
|
|
BT_Phase2StartLanceMugshot,
|
|
BT_Phase2StartBlueMugshot,
|
|
BT_Phase2AntiClockwiseSpiral,
|
|
};
|
|
|
|
static const TransitionStateFunc sBT_MainPhases[] =
|
|
{
|
|
BT_Phase1Blink,
|
|
BT_WaitForPhase1,
|
|
BT_Phase2LaunchAnimTask,
|
|
BT_WaitForPhase2,
|
|
};
|
|
|
|
static const TransitionStateFunc sBT_Phase2BlurFuncs[] =
|
|
{
|
|
BT_Phase2Blur_InitBgMosaic,
|
|
BT_Phase2Blur_Anim,
|
|
BT_Phase2Blur_IsDone,
|
|
};
|
|
|
|
static const TransitionStateFunc sBT_Phase2DistortedWaveFuncs[] =
|
|
{
|
|
BT_Phase2DistortedWave_InitWave,
|
|
BT_Phase2DistortedWave_UpdateWave,
|
|
};
|
|
|
|
static const TransitionStateFunc sBT_Phase2HorizontalCorrugateFuncs[] =
|
|
{
|
|
BT_Phase2HorizontalCorrugate_Init,
|
|
BT_Phase2HorizontalCorrugate_UpdateWave,
|
|
};
|
|
|
|
static const TransitionStateFunc sBT_Phase2BigPokeballFuncs[] =
|
|
{
|
|
BT_Phase2BigPokeball_Init,
|
|
BT_Phase2BigPokeball_LoadTilemapAndWave,
|
|
BT_Phase2BigPokeball_UpdateWave1IncEva,
|
|
BT_Phase2BigPokeball_UpdateWave2DecEvb,
|
|
BT_Phase2BigPokeball_UpdateWave3,
|
|
BT_Phase2BigPokeball_CircleEffect,
|
|
};
|
|
|
|
static const TransitionStateFunc sBT_Phase2SlidingPokeballsFuncs[] =
|
|
{
|
|
BT_Phase2SlidingPokeballs_LoadBgGfx,
|
|
BT_Phase2SlidingPokeballs_SetupFldeffArgs,
|
|
BT_Phase2SlidingPokeballs_IsDone,
|
|
};
|
|
|
|
static const s16 gUnknown_83FA400[] = { -16, 256 };
|
|
|
|
static const s16 gUnknown_83FA404[] = { 0, 16, 32, 8, 24 };
|
|
|
|
static const s16 gUnknown_83FA40E[] = { 8, -8 };
|
|
|
|
static const TransitionStateFunc sBT_Phase2ClockwiseBlackFadeFuncs[] =
|
|
{
|
|
BT_Phase2ClockwiseBlackFade_Init,
|
|
BT_Phase2ClockwiseBlackFade_Step1,
|
|
BT_Phase2ClockwiseBlackFade_Step2,
|
|
BT_Phase2ClockwiseBlackFade_Step3,
|
|
BT_Phase2ClockwiseBlackFade_Step4,
|
|
BT_Phase2ClockwiseBlackFade_Step5,
|
|
BT_Phase2ClockwiseBlackFade_End,
|
|
};
|
|
|
|
static const TransitionStateFunc sBT_Phase2FullScreenWaveFuncs[] =
|
|
{
|
|
BT_Phase2FullScreenWave_Init,
|
|
BT_Phase2FullScreenWave_UpdateWave,
|
|
};
|
|
|
|
static const TransitionStateFunc sBT_Phase2BlackWaveToRightFuncs[] =
|
|
{
|
|
BT_Phase2BlackWaveToRight_Init,
|
|
BT_Phase2BlackWaveToRight_UpdateWave,
|
|
BT_Phase2BlackWaveToRight_End,
|
|
};
|
|
static const s16 gUnknown_83FA444[] =
|
|
{
|
|
0x0, 0x26E,
|
|
0x100, 0x69,
|
|
0x0, -0x69,
|
|
-0x100, -0x266E,
|
|
0x0, 0x26E,
|
|
0x100, 0x69,
|
|
0x0, -0x69,
|
|
-0x100, -0x266E,
|
|
};
|
|
|
|
static const TransitionStateFunc sBT_Phase2AntiClockwiseSpiralFuncs[] =
|
|
{
|
|
BT_Phase2AntiClockwiseSpiral_Init,
|
|
BT_Phase2AntiClockwiseSpiral_Update,
|
|
};
|
|
|
|
static const TransitionStateFunc sBT_Phase2MugshotFuncs[] =
|
|
{
|
|
BT_Phase2Mugshot_Init,
|
|
BT_Phase2Mugshot_LoadGfx,
|
|
BT_Phase2Mugshot_VsBarsSlideIn,
|
|
BT_Phase2Mugshot_StartSpriteSlide,
|
|
BT_Phase2Mugshot_WaitForOpponentInPlace,
|
|
BT_Phase2Mugshot_WaitForPlayerInPlace,
|
|
BT_Phase2Mugshot_ExpandWhiteBand,
|
|
BT_Phase2Mugshot_StartBlackFade,
|
|
BT_Phase2Mugshot_WaitForBlackFade,
|
|
BT_Phase2Mugshot_End,
|
|
};
|
|
|
|
static const u8 sMugshotsTrainerPicIDsTable[MUGSHOTS_COUNT] =
|
|
{
|
|
// TODO: document these with macro
|
|
0x70, 0x71, 0x72, 0x73, 0x7D
|
|
};
|
|
|
|
static const s16 sMugshotsOpponentRotationScales[MUGSHOTS_COUNT][2] =
|
|
{
|
|
{0x200, 0x200},
|
|
{0x200, 0x200},
|
|
{0x200, 0x200},
|
|
{0x200, 0x200},
|
|
{0x200, 0x200},
|
|
};
|
|
|
|
static const s16 sMugshotsOpponentCoords[MUGSHOTS_COUNT][2] =
|
|
{
|
|
{ -8, 0 },
|
|
{ -10, 0 },
|
|
{ 0, 0 },
|
|
{ -32, 0 },
|
|
{ 0, 0 },
|
|
};
|
|
|
|
static const TransitionSpriteCallback sBT_Phase2MugshotSpriteFuncs[] =
|
|
{
|
|
BT_Phase2MugshotsSpriteFuncs_Wait,
|
|
BT_Phase2MugshotsSpriteFuncs_InitParams,
|
|
BT_Phase2MugshotsSpriteFuncs_SlideSpriteIn,
|
|
BT_Phase2MugshotsSpriteFuncs_DecelerateSprite,
|
|
BT_Phase2MugshotsSpriteFuncs_Wait,
|
|
BT_Phase2MugshotsSpriteFuncs_DecelerateSprite2, // not used
|
|
BT_Phase2MugshotsSpriteFuncs_Wait,
|
|
};
|
|
|
|
static const s16 sMugShotSlideVelocity[] = { 12, -12 };
|
|
|
|
static const s16 sMugShotSlideDeceleration[] = { -1, 1 };
|
|
|
|
static const TransitionStateFunc sBT_Phase2SlicedScreenFuncs[] =
|
|
{
|
|
BT_Phase2SlicedScreen_Init,
|
|
BT_Phase2SlicedScreen_UpdateOffsets,
|
|
BT_Phase2SlicedScreen_End,
|
|
};
|
|
|
|
static const TransitionStateFunc sBT_Phase2WhiteFadeInStripesFuncs[] =
|
|
{
|
|
BT_Phase2WhiteFadeInStripes_Init,
|
|
BT_Phase2WhiteFadeInStripes_SetupSprites,
|
|
BT_Phase2WhiteFadeInStripes_IsWhiteFadeDone,
|
|
BT_Phase2WhiteFadeInStripes_Stop,
|
|
BT_Phase2WhiteFadeInStripes_IsDone,
|
|
};
|
|
|
|
static const u16 sWhiteStripeDelay[] = { 0, 9, 15, 6, 12, 3 };
|
|
|
|
static const TransitionStateFunc sBT_Phase2GridSquaresFuncs[] =
|
|
{
|
|
BT_Phase2GridSquares_LoadGfx,
|
|
BT_Phase2GridSquares_UpdateTileset,
|
|
BT_Phase2GridSquares_IsDone,
|
|
};
|
|
|
|
static const TransitionStateFunc sBT_Phase2BlackDoodlesFuncs[] =
|
|
{
|
|
BT_Phase2BlackDoodles_Init,
|
|
BT_Phase2BlackDoodles_InitSingleBrush,
|
|
BT_Phase2BlackDoodles_DrawSingleBrush,
|
|
BT_Phase2BlackDoodles_IsDone,
|
|
BT_Phase2BlackDoodles_NextBrush,
|
|
};
|
|
|
|
static const s16 sBlackDoodlesSegments[][5] =
|
|
{
|
|
{ 0x38, 0x00, 0x00, 0xA0, 0 },
|
|
{ 0x68, 0xA0, 0xF0, 0x58, 1 },
|
|
{ 0xF0, 0x48, 0x38, 0x00, 1 },
|
|
{ 0x00, 0x20, 0x90, 0xA0, 0 },
|
|
{ 0x90, 0xA0, 0xB8, 0x00, 1 },
|
|
{ 0x38, 0x00, 0xA8, 0xA0, 0 },
|
|
{ 0xA8, 0xA0, 0x30, 0x00, 1 },
|
|
};
|
|
|
|
static const s16 sBlackDoodlesDelay[] = { 1, 1, 1, 1, 1, 1, 0 };
|
|
|
|
static const TransitionStateFunc sBT_Phase1FadeFuncs[] =
|
|
{
|
|
BT_Phase1_FadeOut,
|
|
BT_Phase1_FadeIn,
|
|
};
|
|
|
|
static const struct SpriteFrameImage sSpriteImageTable_SlidingPokeball[] =
|
|
{
|
|
{
|
|
.data = sSpriteImage_SlidingPokeball,
|
|
.size = 0x200,
|
|
},
|
|
};
|
|
|
|
static const union AnimCmd sSpriteAnim_SlidingPokeball[] =
|
|
{
|
|
ANIMCMD_FRAME(0, 1),
|
|
ANIMCMD_END,
|
|
};
|
|
|
|
static const union AnimCmd *const sSpriteAnimTable_SlidingPokeball[] = { sSpriteAnim_SlidingPokeball };
|
|
|
|
static const union AffineAnimCmd sSpriteAffineAnim_SlidingPokeball1[] =
|
|
{
|
|
AFFINEANIMCMD_FRAME(0, 0, -4, 1),
|
|
AFFINEANIMCMD_JUMP(0),
|
|
};
|
|
|
|
static const union AffineAnimCmd sSpriteAffineAnim_SlidingPokeball2[] =
|
|
{
|
|
AFFINEANIMCMD_FRAME(0, 0, 4, 1),
|
|
AFFINEANIMCMD_JUMP(0),
|
|
};
|
|
|
|
static const union AffineAnimCmd *const sSpriteAffineAnimTable_SlidingPokeball[] =
|
|
{
|
|
sSpriteAffineAnim_SlidingPokeball1,
|
|
sSpriteAffineAnim_SlidingPokeball2,
|
|
};
|
|
|
|
static const struct SpriteTemplate sSpriteTemplate_SlidingPokeball =
|
|
{
|
|
.tileTag = SPRITE_INVALID_TAG,
|
|
.paletteTag = 0x1009,
|
|
.oam = &gEventObjectBaseOam_32x32,
|
|
.anims = sSpriteAnimTable_SlidingPokeball,
|
|
.images = sSpriteImageTable_SlidingPokeball,
|
|
.affineAnims = sSpriteAffineAnimTable_SlidingPokeball,
|
|
.callback = SpriteCB_BT_Phase2SlidingPokeballs,
|
|
};
|
|
|
|
static const struct OamData sOamData_Unused =
|
|
{
|
|
.y = 0,
|
|
.affineMode = 0,
|
|
.objMode = 0,
|
|
.mosaic = 0,
|
|
.bpp = 0,
|
|
.shape = SPRITE_SHAPE(64x64),
|
|
.x = 0,
|
|
.matrixNum = 0,
|
|
.size = SPRITE_SIZE(64x64),
|
|
.tileNum = 0,
|
|
.priority = 0,
|
|
.paletteNum = 0,
|
|
.affineParam = 0,
|
|
};
|
|
|
|
static const struct SpriteFrameImage sSpriteImageTable_UnusedBrendan[] =
|
|
{
|
|
{
|
|
.data = sSpriteImage_UnusedBrendan,
|
|
.size = 0x800,
|
|
},
|
|
};
|
|
|
|
static const struct SpriteFrameImage sSpriteImageTable_UnusedLass[] =
|
|
{
|
|
{
|
|
.data = sSpriteImage_UnusedLass,
|
|
.size = 0x800,
|
|
},
|
|
};
|
|
|
|
static const union AnimCmd sSpriteAnim_Unused[] =
|
|
{
|
|
ANIMCMD_FRAME(0, 1),
|
|
ANIMCMD_END,
|
|
};
|
|
|
|
static const union AnimCmd *const sSpriteAnimTable_Unused[] = { sSpriteAnim_Unused };
|
|
|
|
static const struct SpriteTemplate sSpriteTemplateTable_Unused[] =
|
|
{
|
|
{
|
|
.tileTag = SPRITE_INVALID_TAG,
|
|
.paletteTag = 0x100A,
|
|
.oam = &sOamData_Unused,
|
|
.anims = sSpriteAnimTable_Unused,
|
|
.images = sSpriteImageTable_UnusedBrendan,
|
|
.affineAnims = gDummySpriteAffineAnimTable,
|
|
.callback = SpriteCB_BT_Phase2Mugshots,
|
|
},
|
|
{
|
|
.tileTag = SPRITE_INVALID_TAG,
|
|
.paletteTag = 0x100A,
|
|
.oam = &sOamData_Unused,
|
|
.anims = sSpriteAnimTable_Unused,
|
|
.images = sSpriteImageTable_UnusedLass,
|
|
.affineAnims = gDummySpriteAffineAnimTable,
|
|
.callback = SpriteCB_BT_Phase2Mugshots,
|
|
},
|
|
};
|
|
|
|
// this palette is shared by big pokeball and sliding pokeball
|
|
static const u16 sSlidingPokeballBigPokeballPalette[] = INCBIN_U16("graphics/battle_transitions/sliding_pokeball.gbapal");
|
|
|
|
static const struct SpritePalette sSpritePalette_SlidingPokeball =
|
|
{
|
|
.data = sSlidingPokeballBigPokeballPalette,
|
|
.tag = 0x1009,
|
|
};
|
|
|
|
static const u16 sVsBarLoreleiPalette[] = INCBIN_U16("graphics/battle_transitions/lorelei_bg.gbapal");
|
|
static const u16 sVsBarBrunoPalette[] = INCBIN_U16("graphics/battle_transitions/bruno_bg.gbapal");
|
|
static const u16 sVsBarAgathaPalette[] = INCBIN_U16("graphics/battle_transitions/agatha_bg.gbapal");
|
|
static const u16 sVsBarLancePalette[] = INCBIN_U16("graphics/battle_transitions/lance_bg.gbapal");
|
|
static const u16 sVsBarBluePalette[] = INCBIN_U16("graphics/battle_transitions/blue_bg.gbapal");
|
|
static const u16 sVsBarMalePlayerPalette[] = INCBIN_U16("graphics/battle_transitions/red_bg.gbapal");
|
|
static const u16 sVsBarFemalePlayerPalette[] = INCBIN_U16("graphics/battle_transitions/green_bg.gbapal");
|
|
|
|
static const u16 *const sVsBarOpponentPalettes[MUGSHOTS_COUNT] =
|
|
{
|
|
sVsBarLoreleiPalette,
|
|
sVsBarBrunoPalette,
|
|
sVsBarAgathaPalette,
|
|
sVsBarLancePalette,
|
|
sVsBarBluePalette,
|
|
};
|
|
|
|
static const u16 *const sVsBarPlayerPalettes[] =
|
|
{
|
|
sVsBarMalePlayerPalette,
|
|
sVsBarFemalePlayerPalette,
|
|
};
|
|
|
|
static const u16 sUnusedTrainerPalette[] = INCBIN_U16("graphics/battle_transitions/unused_trainer.gbapal");
|
|
|
|
static const struct SpritePalette sSpritePalette_UnusedTrainer =
|
|
{
|
|
.data = sUnusedTrainerPalette,
|
|
.tag = 0x100A,
|
|
};
|
|
|
|
static const u16 sBigPokeballTilemap[] = INCBIN_U16("graphics/battle_transitions/big_pokeball_tilemap.bin");
|
|
static const u16 sVsBarTilemap[] = INCBIN_U16("graphics/battle_transitions/vsbar_tilemap.bin");
|
|
|
|
void BT_StartOnField(u8 transitionId)
|
|
{
|
|
sTransitionStructPtr = AllocZeroed(sizeof(struct TransitionData));
|
|
gMain.callback2 = CB2_OverworldBasic;
|
|
BT_LaunchTask(transitionId);
|
|
}
|
|
|
|
// not used
|
|
static void BT_StartWithoutAlloc(u8 transitionId)
|
|
{
|
|
BT_LaunchTask(transitionId);
|
|
}
|
|
|
|
#define tState data[0]
|
|
#define tTransitionId data[1]
|
|
#define tTransitionDone data[15]
|
|
|
|
bool8 BT_IsDone(void)
|
|
{
|
|
u8 taskId = FindTaskIdByFunc(BT_TaskMain);
|
|
if (gTasks[taskId].tTransitionDone)
|
|
{
|
|
BT_InitCtrlBlk();
|
|
FREE_AND_SET_NULL(sTransitionStructPtr);
|
|
DestroyTask(taskId);
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
static void BT_LaunchTask(u8 transitionId)
|
|
{
|
|
u8 taskId = CreateTask(BT_TaskMain, 2);
|
|
gTasks[taskId].tTransitionId = transitionId;
|
|
}
|
|
|
|
static void BT_TaskMain(u8 taskId)
|
|
{
|
|
while (sBT_MainPhases[gTasks[taskId].tState](&gTasks[taskId]));
|
|
}
|
|
|
|
static bool8 BT_Phase1Blink(struct Task *task)
|
|
{
|
|
SetWeatherScreenFadeOut();
|
|
CpuCopy32(gPlttBufferFaded, gPlttBufferUnfaded, 0x400);
|
|
if (sBT_Phase1Tasks[task->tTransitionId] != NULL)
|
|
{
|
|
CreateTask(sBT_Phase1Tasks[task->tTransitionId], 4);
|
|
++task->tState;
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
task->tState = 2;
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
static bool8 BT_WaitForPhase1(struct Task *task)
|
|
{
|
|
if (FindTaskIdByFunc(sBT_Phase1Tasks[task->tTransitionId]) == TASK_NONE)
|
|
{
|
|
++task->tState;
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
static bool8 BT_Phase2LaunchAnimTask(struct Task *task)
|
|
{
|
|
CreateTask(sBT_Phase2Tasks[task->tTransitionId], 0);
|
|
++task->tState;
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 BT_WaitForPhase2(struct Task *task)
|
|
{
|
|
task->tTransitionDone = FALSE;
|
|
if (FindTaskIdByFunc(sBT_Phase2Tasks[task->tTransitionId]) == TASK_NONE)
|
|
task->tTransitionDone = TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
static void BT_Phase1Task(u8 taskId)
|
|
{
|
|
if (!gTasks[taskId].tState)
|
|
{
|
|
++gTasks[taskId].tState;
|
|
BT_CreatePhase1SubTask(0, 0, 2, 2, 2);
|
|
}
|
|
else if (BT_IsPhase1Done())
|
|
{
|
|
DestroyTask(taskId);
|
|
}
|
|
}
|
|
|
|
#define tInterval data[1]
|
|
#define tMosaicSize data[2]
|
|
|
|
static void BT_Phase2Blur(u8 taskId)
|
|
{
|
|
while (sBT_Phase2BlurFuncs[gTasks[taskId].tState](&gTasks[taskId]));
|
|
}
|
|
|
|
static bool8 BT_Phase2Blur_InitBgMosaic(struct Task *task)
|
|
{
|
|
SetGpuReg(REG_OFFSET_MOSAIC, 0);
|
|
SetGpuRegBits(REG_OFFSET_BG1CNT, BGCNT_MOSAIC);
|
|
SetGpuRegBits(REG_OFFSET_BG2CNT, BGCNT_MOSAIC);
|
|
SetGpuRegBits(REG_OFFSET_BG3CNT, BGCNT_MOSAIC);
|
|
++task->tState;
|
|
return TRUE;
|
|
}
|
|
|
|
static bool8 BT_Phase2Blur_Anim(struct Task *task)
|
|
{
|
|
if (task->tInterval)
|
|
{
|
|
--task->tInterval;
|
|
}
|
|
else
|
|
{
|
|
task->tInterval = 2;
|
|
if (++task->tMosaicSize == 10)
|
|
BeginNormalPaletteFade(0xFFFFFFFF, -1, 0, 0x10, RGB_BLACK);
|
|
// The mosaic size argument is shared by HSIZE and VSIZE
|
|
SetGpuReg(REG_OFFSET_MOSAIC, (task->tMosaicSize & 0xF) + ((task->tMosaicSize & 0xF) << 4));
|
|
if (task->tMosaicSize > 14)
|
|
++task->tState;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 BT_Phase2Blur_IsDone(struct Task *task)
|
|
{
|
|
if (!gPaletteFade.active)
|
|
DestroyTask(FindTaskIdByFunc(BT_Phase2Blur));
|
|
return FALSE;
|
|
}
|
|
|
|
#undef tInterval
|
|
#undef tMosaicSize
|
|
|
|
#define tTheta data[1]
|
|
#define tAmplitude data[2]
|
|
|
|
static void BT_Phase2DistortedWave(u8 taskId)
|
|
{
|
|
while (sBT_Phase2DistortedWaveFuncs[gTasks[taskId].tState](&gTasks[taskId]));
|
|
}
|
|
|
|
static bool8 BT_Phase2DistortedWave_InitWave(struct Task *task)
|
|
{
|
|
BT_InitCtrlBlk();
|
|
ScanlineEffect_Clear();
|
|
BeginNormalPaletteFade(0xFFFFFFFF, 4, 0, 0x10, RGB_BLACK);
|
|
BT_LoadWaveIntoBuffer(gScanlineEffectRegBuffers[1], sTransitionStructPtr->bg123HOfs, 0, 2, 0, 160);
|
|
SetVBlankCallback(VBCB_BT_Phase2DistortedWave);
|
|
SetHBlankCallback(HBCB_BT_Phase2DistortedWave);
|
|
EnableInterrupts(INTR_FLAG_VBLANK | INTR_FLAG_HBLANK);
|
|
++task->tState;
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 BT_Phase2DistortedWave_UpdateWave(struct Task *task)
|
|
{
|
|
sTransitionStructPtr->vblankDma = FALSE;
|
|
task->tTheta += 4;
|
|
task->tAmplitude += 8;
|
|
BT_LoadWaveIntoBuffer(gScanlineEffectRegBuffers[0], sTransitionStructPtr->bg123HOfs, task->tTheta, 2, task->tAmplitude, 160);
|
|
if (!gPaletteFade.active)
|
|
DestroyTask(FindTaskIdByFunc(BT_Phase2DistortedWave));
|
|
++sTransitionStructPtr->vblankDma;
|
|
return FALSE;
|
|
}
|
|
|
|
static void VBCB_BT_Phase2DistortedWave(void)
|
|
{
|
|
BT_VBSyncOamAndPltt();
|
|
if (sTransitionStructPtr->vblankDma)
|
|
DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320);
|
|
}
|
|
|
|
static void HBCB_BT_Phase2DistortedWave(void)
|
|
{
|
|
s16 offset = gScanlineEffectRegBuffers[1][REG_VCOUNT];
|
|
|
|
REG_BG1HOFS = offset;
|
|
REG_BG2HOFS = offset;
|
|
REG_BG3HOFS = offset;
|
|
}
|
|
|
|
static void BT_Phase2HorizontalCorrugate(u8 taskId)
|
|
{
|
|
while (sBT_Phase2HorizontalCorrugateFuncs[gTasks[taskId].tState](&gTasks[taskId]));
|
|
}
|
|
|
|
static bool8 BT_Phase2HorizontalCorrugate_Init(struct Task *task)
|
|
{
|
|
BT_InitCtrlBlk();
|
|
ScanlineEffect_Clear();
|
|
BeginNormalPaletteFade(0xFFFFFFFF, 4, 0, 0x10, RGB_BLACK);
|
|
memset(gScanlineEffectRegBuffers[1], sTransitionStructPtr->bg123VOfs, 320);
|
|
SetVBlankCallback(VBCB_BT_Phase2HorizontalCorrugate);
|
|
SetHBlankCallback(HBCB_BT_Phase2HorizontalCorrugate);
|
|
EnableInterrupts(INTR_FLAG_VBLANK | INTR_FLAG_HBLANK);
|
|
++task->tState;
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 BT_Phase2HorizontalCorrugate_UpdateWave(struct Task *task)
|
|
{
|
|
u8 i;
|
|
u16 theta, amplitude;
|
|
|
|
sTransitionStructPtr->vblankDma = FALSE;
|
|
theta = task->tTheta;
|
|
amplitude = task->tAmplitude >> 8;
|
|
task->tTheta += 4224;
|
|
task->tAmplitude += 384;
|
|
for (i = 0; i < 160; ++i, theta += 4224)
|
|
gScanlineEffectRegBuffers[0][i] = sTransitionStructPtr->bg123VOfs + Sin(theta / 256, amplitude);
|
|
if (!gPaletteFade.active)
|
|
DestroyTask(FindTaskIdByFunc(BT_Phase2HorizontalCorrugate));
|
|
++sTransitionStructPtr->vblankDma;
|
|
return FALSE;
|
|
}
|
|
|
|
static void VBCB_BT_Phase2HorizontalCorrugate(void)
|
|
{
|
|
BT_VBSyncOamAndPltt();
|
|
if (sTransitionStructPtr->vblankDma)
|
|
DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320);
|
|
}
|
|
|
|
static void HBCB_BT_Phase2HorizontalCorrugate(void)
|
|
{
|
|
s16 offset = gScanlineEffectRegBuffers[1][REG_VCOUNT];
|
|
|
|
REG_BG1VOFS = offset;
|
|
REG_BG2VOFS = offset;
|
|
REG_BG3VOFS = offset;
|
|
}
|
|
|
|
#undef tTheta
|
|
#undef tAmplitude
|
|
|
|
#define tEvb data[1]
|
|
#define tEva data[2]
|
|
#define tInterval data[3]
|
|
#define tTheta data[4]
|
|
#define tAmplitude data[5]
|
|
|
|
static void BT_Phase2BigPokeball(u8 taskId)
|
|
{
|
|
while (sBT_Phase2BigPokeballFuncs[gTasks[taskId].tState](&gTasks[taskId]));
|
|
}
|
|
|
|
static bool8 BT_Phase2BigPokeball_Init(struct Task *task)
|
|
{
|
|
u16 i, *tilemapAddr, *tilesetAddr;
|
|
|
|
BT_InitCtrlBlk();
|
|
ScanlineEffect_Clear();
|
|
task->tEvb = 16;
|
|
task->tEva = 0;
|
|
task-> tTheta = 0;
|
|
task-> tAmplitude = 0x4000;
|
|
sTransitionStructPtr->winIn = WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR;
|
|
sTransitionStructPtr->winOut = 0;
|
|
sTransitionStructPtr->win0H = WIN_RANGE(0, 0xF0);
|
|
sTransitionStructPtr->win0V = WIN_RANGE(0, 0xA0);
|
|
sTransitionStructPtr->bldCnt = BLDCNT_TGT1_BG0 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG0 | BLDCNT_TGT2_BG1 | BLDCNT_TGT2_BG2 | BLDCNT_TGT2_BG3 | BLDCNT_TGT2_OBJ | BLDCNT_TGT2_BD;
|
|
sTransitionStructPtr->bldAlpha = (task->tEvb << 8) | task->tEva;
|
|
for (i = 0; i < 160; ++i)
|
|
gScanlineEffectRegBuffers[1][i] = 0xF0;
|
|
SetVBlankCallback(VBCB_BT_Phase2BigPokeball1);
|
|
BT_GetBg0TilemapAndTilesetBase(&tilemapAddr, &tilesetAddr);
|
|
CpuFill16(0, tilemapAddr, 0x800);
|
|
CpuCopy16(sBigPokeballTileset, tilesetAddr, 0x580);
|
|
LoadPalette(sSlidingPokeballBigPokeballPalette, 0xF0, 0x20);
|
|
++task->tState;
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 BT_Phase2BigPokeball_LoadTilemapAndWave(struct Task *task)
|
|
{
|
|
s16 i, j;
|
|
u16 *tilemapAddr, *tilesetAddr;
|
|
const u16 *BigPokeballMap = sBigPokeballTilemap;
|
|
|
|
BT_GetBg0TilemapAndTilesetBase(&tilemapAddr, &tilesetAddr);
|
|
for (i = 0; i < 20; ++i)
|
|
for (j = 0; j < 30; ++j, ++BigPokeballMap)
|
|
tilemapAddr[i * 32 + j] = *BigPokeballMap | 0xF000; // use palette #15
|
|
BT_LoadWaveIntoBuffer(gScanlineEffectRegBuffers[0], 0, task->tTheta, 132, task->tAmplitude, 160);
|
|
++task->tState;
|
|
return TRUE;
|
|
}
|
|
|
|
static bool8 BT_Phase2BigPokeball_UpdateWave1IncEva(struct Task *task)
|
|
{
|
|
sTransitionStructPtr->vblankDma = FALSE;
|
|
if (task->tInterval == 0 || --task->tInterval == 0)
|
|
{
|
|
++task->tEva;
|
|
task->tInterval = 1; // Broken logic. This makes the condition always TRUE.
|
|
}
|
|
sTransitionStructPtr->bldAlpha = BLDALPHA_BLEND(task->tEva, task->tEvb);
|
|
// Increment eva until it reaches 50% coeff
|
|
if (task->tEva > 15)
|
|
++task->tState;
|
|
task->tTheta += 12;
|
|
task->tAmplitude -= 384;
|
|
// Assign a very high frequency value so that 2 adjacent values in gScanlineEffectRegBuffers[0] will have different sign.
|
|
BT_LoadWaveIntoBuffer(gScanlineEffectRegBuffers[0], 0, task->tTheta, 132, task->tAmplitude >> 8, 160);
|
|
++sTransitionStructPtr->vblankDma;
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 BT_Phase2BigPokeball_UpdateWave2DecEvb(struct Task *task)
|
|
{
|
|
sTransitionStructPtr->vblankDma = FALSE;
|
|
if (task->tInterval == 0 || --task->tInterval == 0)
|
|
{
|
|
--task->tEvb;
|
|
task->tInterval = 2;
|
|
}
|
|
sTransitionStructPtr->bldAlpha = (task->tEvb << 8) | task->tEva;
|
|
if (!task->tEvb)
|
|
++task->tState;
|
|
if (task->tAmplitude > 0)
|
|
{
|
|
task->tTheta += 12;
|
|
task->tAmplitude -= 384;
|
|
}
|
|
else
|
|
{
|
|
task->tAmplitude = 0;
|
|
}
|
|
BT_LoadWaveIntoBuffer(gScanlineEffectRegBuffers[0], 0, task->tTheta, 132, task->tAmplitude >> 8, 160);
|
|
++sTransitionStructPtr->vblankDma;
|
|
return FALSE;
|
|
}
|
|
|
|
#undef tEvb
|
|
#undef tEva
|
|
#undef tInterval
|
|
|
|
#define tRadius data[1]
|
|
#define tDeltaRadius data[2]
|
|
#define tKeepVBCB data[3]
|
|
|
|
static bool8 BT_Phase2BigPokeball_UpdateWave3(struct Task *task)
|
|
{
|
|
sTransitionStructPtr->vblankDma = FALSE;
|
|
if (task->tAmplitude > 0)
|
|
{
|
|
task->tTheta += 12;
|
|
task->tAmplitude -= 384;
|
|
}
|
|
else
|
|
{
|
|
task->tAmplitude = 0;
|
|
}
|
|
BT_LoadWaveIntoBuffer(gScanlineEffectRegBuffers[0], 0, task->tTheta, 132, task->tAmplitude >> 8, 160);
|
|
if (task->tAmplitude <= 0)
|
|
{
|
|
++task->tState;
|
|
task->tRadius = 160;
|
|
task->tDeltaRadius = 256;
|
|
task->tKeepVBCB = 0;
|
|
}
|
|
++sTransitionStructPtr->vblankDma;
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 BT_Phase2BigPokeball_CircleEffect(struct Task *task)
|
|
{
|
|
sTransitionStructPtr->vblankDma = FALSE;
|
|
if (task->tDeltaRadius < 2048)
|
|
task->tDeltaRadius += 256;
|
|
if (task->tRadius)
|
|
{
|
|
task->tRadius -= (task->tDeltaRadius >> 8);
|
|
if (task->tRadius < 0)
|
|
task->tRadius = 0;
|
|
}
|
|
BT_GenerateCircle(gScanlineEffectRegBuffers[0], 120, 80, task->tRadius);
|
|
if (task->tRadius == 0)
|
|
{
|
|
DmaStop(0);
|
|
BT_BlendPalettesToBlack();
|
|
DestroyTask(FindTaskIdByFunc(BT_Phase2BigPokeball));
|
|
}
|
|
if (task->tKeepVBCB == 0)
|
|
{
|
|
++task->tKeepVBCB;
|
|
SetVBlankCallback(VBCB_BT_Phase2BigPokeball2);
|
|
}
|
|
++sTransitionStructPtr->vblankDma;
|
|
return FALSE;
|
|
}
|
|
|
|
static void BT_VBStopDma0SyncSrcBufferSetLcdRegs(void)
|
|
{
|
|
DmaStop(0);
|
|
BT_VBSyncOamAndPltt();
|
|
if (sTransitionStructPtr->vblankDma)
|
|
DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320);
|
|
SetGpuReg(REG_OFFSET_WININ, sTransitionStructPtr->winIn);
|
|
SetGpuReg(REG_OFFSET_WINOUT, sTransitionStructPtr->winOut);
|
|
SetGpuReg(REG_OFFSET_WIN0V, sTransitionStructPtr->win0V);
|
|
SetGpuReg(REG_OFFSET_BLDCNT, sTransitionStructPtr->bldCnt);
|
|
SetGpuReg(REG_OFFSET_BLDALPHA, sTransitionStructPtr->bldAlpha);
|
|
}
|
|
|
|
static void VBCB_BT_Phase2BigPokeball1(void)
|
|
{
|
|
BT_VBStopDma0SyncSrcBufferSetLcdRegs();
|
|
DmaSet(0, gScanlineEffectRegBuffers[1], ®_BG0HOFS, ((DMA_ENABLE | DMA_START_HBLANK | DMA_REPEAT | DMA_16BIT | DMA_SRC_INC | DMA_DEST_FIXED) << 16) | 1);
|
|
}
|
|
|
|
static void VBCB_BT_Phase2BigPokeball2(void)
|
|
{
|
|
BT_VBStopDma0SyncSrcBufferSetLcdRegs();
|
|
DmaSet(0, gScanlineEffectRegBuffers[1], ®_WIN0H, ((DMA_ENABLE | DMA_START_HBLANK | DMA_REPEAT | DMA_16BIT | DMA_SRC_INC | DMA_DEST_FIXED) << 16) | 1);
|
|
}
|
|
|
|
#undef tRadius
|
|
#undef tDeltaRadius
|
|
#undef tKeepVBCB
|
|
#undef tTheta
|
|
#undef tAmplitude
|
|
|
|
// TODO: Document this effect after knowing more about field effects.
|
|
static void BT_Phase2SlidingPokeballs(u8 taskId)
|
|
{
|
|
while (sBT_Phase2SlidingPokeballsFuncs[gTasks[taskId].tState](&gTasks[taskId]));
|
|
}
|
|
|
|
static bool8 BT_Phase2SlidingPokeballs_LoadBgGfx(struct Task *task)
|
|
{
|
|
u16 *tilemapAddr, *tilesetAddr;
|
|
|
|
BT_GetBg0TilemapAndTilesetBase(&tilemapAddr, &tilesetAddr);
|
|
CpuSet(sSlidingPokeballTilemap, tilesetAddr, 0x20);
|
|
CpuFill32(0, tilemapAddr, 0x800);
|
|
LoadPalette(sSlidingPokeballBigPokeballPalette, 0xF0, 0x20);
|
|
++task->tState;
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 BT_Phase2SlidingPokeballs_SetupFldeffArgs(struct Task *task)
|
|
{
|
|
s16 i, rand;
|
|
s16 arr0[NELEMS(gUnknown_83FA400)];
|
|
s16 arr1[NELEMS(gUnknown_83FA404)];
|
|
|
|
memcpy(arr0, gUnknown_83FA400, sizeof(gUnknown_83FA400));
|
|
memcpy(arr1, gUnknown_83FA404, sizeof(gUnknown_83FA404));
|
|
rand = Random() & 1;
|
|
for (i = 0; i <= 4; ++i, rand ^= 1)
|
|
{
|
|
gFieldEffectArguments[0] = arr0[rand]; // x
|
|
gFieldEffectArguments[1] = (i * 32) + 16; // y
|
|
gFieldEffectArguments[2] = rand;
|
|
gFieldEffectArguments[3] = arr1[i];
|
|
FieldEffectStart(FLDEFF_POKEBALL);
|
|
}
|
|
++task->tState;
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 BT_Phase2SlidingPokeballs_IsDone(struct Task *task)
|
|
{
|
|
if (!FieldEffectActiveListContains(FLDEFF_POKEBALL))
|
|
{
|
|
BT_BlendPalettesToBlack();
|
|
DestroyTask(FindTaskIdByFunc(BT_Phase2SlidingPokeballs));
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
bool8 FldEff_Pokeball(void)
|
|
{
|
|
u8 spriteId = CreateSpriteAtEnd(&sSpriteTemplate_SlidingPokeball, gFieldEffectArguments[0], gFieldEffectArguments[1], 0);
|
|
|
|
gSprites[spriteId].oam.priority = 0;
|
|
gSprites[spriteId].oam.affineMode = 1;
|
|
gSprites[spriteId].data[0] = gFieldEffectArguments[2];
|
|
gSprites[spriteId].data[1] = gFieldEffectArguments[3];
|
|
gSprites[spriteId].data[2] = -1;
|
|
InitSpriteAffineAnim(&gSprites[spriteId]);
|
|
StartSpriteAffineAnim(&gSprites[spriteId], gFieldEffectArguments[2]);
|
|
return FALSE;
|
|
}
|
|
|
|
#define SOME_VRAM_STORE(ptr, posY, posX, toStore) \
|
|
{ \
|
|
u32 index = (posY) * 32 + posX; \
|
|
ptr[index] = toStore; \
|
|
}
|
|
|
|
static void SpriteCB_BT_Phase2SlidingPokeballs(struct Sprite *sprite)
|
|
{
|
|
s16 arr0[NELEMS(gUnknown_83FA40E)];
|
|
|
|
memcpy(arr0, gUnknown_83FA40E, sizeof(gUnknown_83FA40E));
|
|
if (sprite->data[1])
|
|
{
|
|
--sprite->data[1];
|
|
}
|
|
else
|
|
{
|
|
if ((u16)sprite->pos1.x <= 240)
|
|
{
|
|
s16 posX = sprite->pos1.x >> 3;
|
|
s16 posY = sprite->pos1.y >> 3;
|
|
|
|
if (posX != sprite->data[2])
|
|
{
|
|
u32 var;
|
|
u16 *ptr;
|
|
|
|
sprite->data[2] = posX;
|
|
var = (((GetGpuReg(REG_OFFSET_BG0CNT) >> 8) & 0x1F) << 11);
|
|
ptr = (u16 *)(VRAM + var);
|
|
SOME_VRAM_STORE(ptr, posY - 2, posX, 0xF001);
|
|
SOME_VRAM_STORE(ptr, posY - 1, posX, 0xF001);
|
|
SOME_VRAM_STORE(ptr, posY - 0, posX, 0xF001);
|
|
SOME_VRAM_STORE(ptr, posY + 1, posX, 0xF001);
|
|
}
|
|
}
|
|
sprite->pos1.x += arr0[sprite->data[0]];
|
|
if (sprite->pos1.x < -15 || sprite->pos1.x > 255)
|
|
FieldEffectStop(sprite, FLDEFF_POKEBALL);
|
|
}
|
|
}
|
|
|
|
#define trStartPtX data[0]
|
|
#define trStartPtY data[1]
|
|
#define trCurrentPtX data[2]
|
|
#define trCurrentPtY data[3]
|
|
#define trEndPtX data[4]
|
|
#define trEndPtY data[5]
|
|
|
|
static void BT_Phase2ClockwiseBlackFade(u8 taskId)
|
|
{
|
|
while (sBT_Phase2ClockwiseBlackFadeFuncs[gTasks[taskId].tState](&gTasks[taskId]));
|
|
}
|
|
|
|
static bool8 BT_Phase2ClockwiseBlackFade_Init(struct Task *task)
|
|
{
|
|
u16 i;
|
|
|
|
BT_InitCtrlBlk();
|
|
ScanlineEffect_Clear();
|
|
sTransitionStructPtr->winIn = 0;
|
|
sTransitionStructPtr->winOut = WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR;
|
|
sTransitionStructPtr->win0H = WIN_RANGE(0xF0, 0xF1);
|
|
sTransitionStructPtr->win0V = WIN_RANGE(0, 0xA0);
|
|
for (i = 0; i < 160; ++i)
|
|
gScanlineEffectRegBuffers[1][i] = WIN_RANGE(0xF3, 0xF4);
|
|
SetVBlankCallback(VBCB_BT_Phase2ClockwiseBlackFade);
|
|
sTransitionStructPtr->trEndPtX = 120;
|
|
++task->tState;
|
|
return TRUE;
|
|
}
|
|
|
|
static bool8 BT_Phase2ClockwiseBlackFade_Step1(struct Task *task)
|
|
{
|
|
sTransitionStructPtr->vblankDma = FALSE;
|
|
BT_DiagonalSegment_InitParams(sTransitionStructPtr->data, 120, 80, sTransitionStructPtr->trEndPtX, -1, 1, 1);
|
|
do
|
|
{
|
|
gScanlineEffectRegBuffers[0][sTransitionStructPtr->trCurrentPtY] = WIN_RANGE(0x78, sTransitionStructPtr->trCurrentPtX + 1);
|
|
}
|
|
while (!BT_DiagonalSegment_ComputePointOnSegment(sTransitionStructPtr->data, TRUE, TRUE));
|
|
|
|
sTransitionStructPtr->trEndPtX += 32;
|
|
if (sTransitionStructPtr->trEndPtX >= 240)
|
|
{
|
|
sTransitionStructPtr->trEndPtY = 0;
|
|
++task->tState;
|
|
}
|
|
++sTransitionStructPtr->vblankDma;
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 BT_Phase2ClockwiseBlackFade_Step2(struct Task *task)
|
|
{
|
|
s16 left, right;
|
|
vu8 finished = FALSE;
|
|
|
|
sTransitionStructPtr->vblankDma = FALSE;
|
|
BT_DiagonalSegment_InitParams(sTransitionStructPtr->data, 120, 80, 240, sTransitionStructPtr->trEndPtY, 1, 1);
|
|
while (TRUE)
|
|
{
|
|
left = 120;
|
|
right = sTransitionStructPtr->trCurrentPtX + 1;
|
|
if (sTransitionStructPtr->trEndPtY >= 80)
|
|
{
|
|
left = sTransitionStructPtr->trCurrentPtX;
|
|
right = 240;
|
|
}
|
|
gScanlineEffectRegBuffers[0][sTransitionStructPtr->trCurrentPtY] = WIN_RANGE2(left, right);
|
|
if (finished)
|
|
break;
|
|
finished = BT_DiagonalSegment_ComputePointOnSegment(sTransitionStructPtr->data, TRUE, TRUE);
|
|
}
|
|
sTransitionStructPtr->trEndPtY += 16;
|
|
if (sTransitionStructPtr->trEndPtY >= 160)
|
|
{
|
|
sTransitionStructPtr->trEndPtX = 240;
|
|
++task->tState;
|
|
}
|
|
else
|
|
{
|
|
while (sTransitionStructPtr->trCurrentPtY < sTransitionStructPtr->trEndPtY)
|
|
gScanlineEffectRegBuffers[0][++sTransitionStructPtr->trCurrentPtY] = WIN_RANGE2(left, right);
|
|
}
|
|
++sTransitionStructPtr->vblankDma;
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 BT_Phase2ClockwiseBlackFade_Step3(struct Task *task)
|
|
{
|
|
sTransitionStructPtr->vblankDma = FALSE;
|
|
BT_DiagonalSegment_InitParams(sTransitionStructPtr->data, 120, 80, sTransitionStructPtr->trEndPtX, 160, 1, 1);
|
|
do
|
|
{
|
|
gScanlineEffectRegBuffers[0][sTransitionStructPtr->trCurrentPtY] = (sTransitionStructPtr->trCurrentPtX << 8) | 0xF0;
|
|
}
|
|
while (!BT_DiagonalSegment_ComputePointOnSegment(sTransitionStructPtr->data, TRUE, TRUE));
|
|
sTransitionStructPtr->trEndPtX -= 32;
|
|
if (sTransitionStructPtr->trEndPtX <= 0)
|
|
{
|
|
sTransitionStructPtr->trEndPtY = 160;
|
|
++task->tState;
|
|
}
|
|
++sTransitionStructPtr->vblankDma;
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
* BUG: The following 2 functions are incorrect. The animation after
|
|
* the rotation angle reaches 1.5π will not be displayed.
|
|
*
|
|
* There're 2 problems which need to be solved in order to correct the logic.
|
|
* 1. With current setup, nothing is displayed inside WIN0 and everything
|
|
* is displayed outside WIN0. Thus, if the rotation angle is > 1.5π, it
|
|
* won't be able to handle the situation.
|
|
* 2. The programmer sometimes swapped the place of left and right boundary
|
|
* of WIN0 (see variables left and right), which will sometimes cause right
|
|
* to be smaller than left. In this way, garbage data will be written to WIN0H.
|
|
*/
|
|
static bool8 BT_Phase2ClockwiseBlackFade_Step4(struct Task *task)
|
|
{
|
|
s16 right, left;
|
|
u16 win0H;
|
|
vu8 finished = FALSE;
|
|
|
|
sTransitionStructPtr->vblankDma = FALSE;
|
|
BT_DiagonalSegment_InitParams(sTransitionStructPtr->data, 120, 80, 0, sTransitionStructPtr->trEndPtY, 1, 1);
|
|
while (TRUE)
|
|
{
|
|
right = (gScanlineEffectRegBuffers[0][sTransitionStructPtr->trCurrentPtY]) & 0xFF;
|
|
left = sTransitionStructPtr->trCurrentPtX;
|
|
if (sTransitionStructPtr->trEndPtY <= 80)
|
|
{
|
|
left = 120;
|
|
right = sTransitionStructPtr->trCurrentPtX;
|
|
}
|
|
win0H = WIN_RANGE2(left, right);
|
|
gScanlineEffectRegBuffers[0][sTransitionStructPtr->trCurrentPtY] = win0H;
|
|
if (finished)
|
|
break;
|
|
finished = BT_DiagonalSegment_ComputePointOnSegment(sTransitionStructPtr->data, TRUE, TRUE);
|
|
}
|
|
sTransitionStructPtr->trEndPtY -= 16;
|
|
if (sTransitionStructPtr->trEndPtY <= 0)
|
|
{
|
|
sTransitionStructPtr->trEndPtX = 0;
|
|
++task->tState;
|
|
}
|
|
else
|
|
{
|
|
while (sTransitionStructPtr->trCurrentPtY > sTransitionStructPtr->trEndPtY)
|
|
gScanlineEffectRegBuffers[0][--sTransitionStructPtr->trCurrentPtY] = WIN_RANGE2(left, right);
|
|
}
|
|
++sTransitionStructPtr->vblankDma;
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 BT_Phase2ClockwiseBlackFade_Step5(struct Task *task)
|
|
{
|
|
s16 left, right;
|
|
|
|
sTransitionStructPtr->vblankDma = FALSE;
|
|
BT_DiagonalSegment_InitParams(sTransitionStructPtr->data, 120, 80, sTransitionStructPtr->trEndPtX, 0, 1, 1);
|
|
do
|
|
{
|
|
left = 120;
|
|
right = sTransitionStructPtr->trCurrentPtX;
|
|
if (sTransitionStructPtr->trCurrentPtX >= 120)
|
|
{
|
|
left = 0;
|
|
right = 240;
|
|
}
|
|
gScanlineEffectRegBuffers[0][sTransitionStructPtr->trCurrentPtY] = WIN_RANGE2(left, right);
|
|
}
|
|
while (!BT_DiagonalSegment_ComputePointOnSegment(sTransitionStructPtr->data, TRUE, TRUE));
|
|
sTransitionStructPtr->trEndPtX += 32;
|
|
if (sTransitionStructPtr->trCurrentPtX > 120)
|
|
++task->tState;
|
|
++sTransitionStructPtr->vblankDma;
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 BT_Phase2ClockwiseBlackFade_End(struct Task *task)
|
|
{
|
|
DmaStop(0);
|
|
BT_BlendPalettesToBlack();
|
|
DestroyTask(FindTaskIdByFunc(BT_Phase2ClockwiseBlackFade));
|
|
return FALSE;
|
|
}
|
|
|
|
static void VBCB_BT_Phase2ClockwiseBlackFade(void)
|
|
{
|
|
DmaStop(0);
|
|
BT_VBSyncOamAndPltt();
|
|
if (sTransitionStructPtr->vblankDma)
|
|
DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320);
|
|
SetGpuReg(REG_OFFSET_WININ, sTransitionStructPtr->winIn);
|
|
SetGpuReg(REG_OFFSET_WINOUT, sTransitionStructPtr->winOut);
|
|
SetGpuReg(REG_OFFSET_WIN0V, sTransitionStructPtr->win0V);
|
|
SetGpuReg(REG_OFFSET_WIN0H, gScanlineEffectRegBuffers[1][0]);
|
|
DmaSet(0, gScanlineEffectRegBuffers[1], ®_WIN0H, ((DMA_ENABLE | DMA_START_HBLANK | DMA_REPEAT | DMA_16BIT | DMA_SRC_INC | DMA_DEST_FIXED) << 16) | 1);
|
|
}
|
|
|
|
#undef trStartPtX
|
|
#undef trStartPtY
|
|
#undef trCurrentPtX
|
|
#undef trCurrentPtY
|
|
#undef trEndPtX
|
|
#undef trEndPtY
|
|
|
|
#define tTheta data[1]
|
|
#define tAmplitude data[2]
|
|
#define tDelayForFade data[3]
|
|
#define tStartFade data[4]
|
|
|
|
static void BT_Phase2FullScreenWave(u8 taskId)
|
|
{
|
|
while (sBT_Phase2FullScreenWaveFuncs[gTasks[taskId].tState](&gTasks[taskId]));
|
|
}
|
|
|
|
static bool8 BT_Phase2FullScreenWave_Init(struct Task *task)
|
|
{
|
|
u8 i;
|
|
|
|
BT_InitCtrlBlk();
|
|
ScanlineEffect_Clear();
|
|
for (i = 0; i < 160; ++i)
|
|
gScanlineEffectRegBuffers[1][i] = sTransitionStructPtr->bg123VOfs;
|
|
SetVBlankCallback(VBCB_BT_Phase2FullScreenWave);
|
|
SetHBlankCallback(HBCB_BT_Phase2FullScreenWave);
|
|
EnableInterrupts(INTR_FLAG_HBLANK);
|
|
++task->tState;
|
|
return TRUE;
|
|
}
|
|
|
|
static bool8 BT_Phase2FullScreenWave_UpdateWave(struct Task *task)
|
|
{
|
|
u8 i;
|
|
s16 amplitude;
|
|
u16 theta, frequency;
|
|
|
|
sTransitionStructPtr->vblankDma = FALSE;
|
|
amplitude = task->tAmplitude >> 8;
|
|
theta = task->tTheta;
|
|
frequency = 384;
|
|
task->tTheta += 0x400;
|
|
if (task->tAmplitude <= 0x1FFF)
|
|
task->tAmplitude += 384;
|
|
for (i = 0; i < 160; ++i, theta += frequency)
|
|
{
|
|
s16 var = theta >> 8;
|
|
|
|
++var;
|
|
--var;
|
|
gScanlineEffectRegBuffers[0][i] = sTransitionStructPtr->bg123VOfs + Sin(var, amplitude);
|
|
}
|
|
if (++task->tDelayForFade == 41)
|
|
{
|
|
++task->tStartFade;
|
|
BeginNormalPaletteFade(0xFFFFFFFF, -8, 0, 0x10, RGB_BLACK);
|
|
}
|
|
if (task->tStartFade && !gPaletteFade.active)
|
|
DestroyTask(FindTaskIdByFunc(BT_Phase2FullScreenWave));
|
|
++sTransitionStructPtr->vblankDma;
|
|
return FALSE;
|
|
}
|
|
|
|
static void VBCB_BT_Phase2FullScreenWave(void)
|
|
{
|
|
BT_VBSyncOamAndPltt();
|
|
if (sTransitionStructPtr->vblankDma)
|
|
DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320);
|
|
}
|
|
|
|
static void HBCB_BT_Phase2FullScreenWave(void)
|
|
{
|
|
s16 offset = gScanlineEffectRegBuffers[1][REG_VCOUNT];
|
|
|
|
REG_BG1VOFS = offset;
|
|
REG_BG2VOFS = offset;
|
|
REG_BG3VOFS = offset;
|
|
}
|
|
|
|
#undef tTheta
|
|
#undef tAmplitude
|
|
#undef tDelayForFade
|
|
#undef tStartFade
|
|
|
|
#define tOffset data[1]
|
|
#define tTheta data[2]
|
|
|
|
static void BT_Phase2BlackWaveToRight(u8 taskId)
|
|
{
|
|
while (sBT_Phase2BlackWaveToRightFuncs[gTasks[taskId].tState](&gTasks[taskId]));
|
|
}
|
|
|
|
static bool8 BT_Phase2BlackWaveToRight_Init(struct Task *task)
|
|
{
|
|
u8 i;
|
|
|
|
BT_InitCtrlBlk();
|
|
ScanlineEffect_Clear();
|
|
sTransitionStructPtr->winIn = WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR;
|
|
sTransitionStructPtr->winOut = 0;
|
|
sTransitionStructPtr->win0H = WIN_RANGE(0, 0xF0);
|
|
sTransitionStructPtr->win0V = WIN_RANGE(0, 0xA0);
|
|
for (i = 0; i < 160; ++i)
|
|
gScanlineEffectRegBuffers[1][i] = WIN_RANGE(0, 0xF2);
|
|
SetVBlankCallback(VBCB_BT_Phase2BlackWaveToRight);
|
|
++task->tState;
|
|
return TRUE;
|
|
}
|
|
|
|
static bool8 BT_Phase2BlackWaveToRight_UpdateWave(struct Task *task)
|
|
{
|
|
u8 i, theta;
|
|
u16 *winVal;
|
|
bool8 nextFunc;
|
|
|
|
sTransitionStructPtr->vblankDma = FALSE;
|
|
winVal = gScanlineEffectRegBuffers[0];
|
|
theta = task->tTheta;
|
|
task->tTheta += 16;
|
|
task->tOffset += 8;
|
|
for (i = 0, nextFunc = TRUE; i < 160; ++i, theta += 4, ++winVal)
|
|
{
|
|
s16 left = task->tOffset + Sin(theta, 40);
|
|
if (left < 0)
|
|
left = 0;
|
|
if (left > 240)
|
|
left = 240;
|
|
*winVal = WIN_RANGE(left, 0xF1);
|
|
if (left < 240)
|
|
nextFunc = FALSE;
|
|
}
|
|
if (nextFunc)
|
|
++task->tState;
|
|
++sTransitionStructPtr->vblankDma;
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 BT_Phase2BlackWaveToRight_End(struct Task *task)
|
|
{
|
|
DmaStop(0);
|
|
BT_BlendPalettesToBlack();
|
|
DestroyTask(FindTaskIdByFunc(BT_Phase2BlackWaveToRight));
|
|
return FALSE;
|
|
}
|
|
|
|
static void VBCB_BT_Phase2BlackWaveToRight(void)
|
|
{
|
|
DmaStop(0);
|
|
BT_VBSyncOamAndPltt();
|
|
if (sTransitionStructPtr->vblankDma)
|
|
DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320);
|
|
SetGpuReg(REG_OFFSET_WININ, sTransitionStructPtr->winIn);
|
|
SetGpuReg(REG_OFFSET_WINOUT, sTransitionStructPtr->winOut);
|
|
SetGpuReg(REG_OFFSET_WIN0V, sTransitionStructPtr->win0V);
|
|
DmaSet(0, gScanlineEffectRegBuffers[1], ®_WIN0H, ((DMA_ENABLE | DMA_START_HBLANK | DMA_REPEAT | DMA_SRC_INC | DMA_DEST_FIXED) << 16) | 1);
|
|
}
|
|
|
|
#undef tOffset
|
|
#undef tTheta
|
|
|
|
static void BT_Phase2AntiClockwiseSpiral(u8 taskId)
|
|
{
|
|
while (sBT_Phase2AntiClockwiseSpiralFuncs[gTasks[taskId].tState](&gTasks[taskId]));
|
|
}
|
|
|
|
#ifdef NONMATCHING
|
|
static void sub_80D1F64(s16 a1, s16 a2, u8 a3)
|
|
{
|
|
s16 i, j;
|
|
|
|
u8 theta = 0;
|
|
for (i = 320; i < 960; ++i)
|
|
gScanlineEffectRegBuffers[1][i] = 120;
|
|
for (i = 0; i < (a2 << 4); ++i, ++theta)
|
|
{
|
|
s16 res1, res2, res3, res4, diff, r8, r0;
|
|
|
|
// PROBLEM #1:
|
|
// (around line 50 in ASM)
|
|
// This part completely doesn't match.
|
|
// It's also not tail merge.
|
|
if ((theta >> 3) != ((theta + 1) >> 3))
|
|
{
|
|
r8 = (theta >> 3) + a1;
|
|
++r8;
|
|
r0 = (theta >> 3) + a1;
|
|
}
|
|
else
|
|
{
|
|
r0 = (theta >> 3) + a1;
|
|
r8 = (theta >> 3) + a1;
|
|
}
|
|
res1 = 80 - Sin(theta, r0);
|
|
res2 = Cos(theta, r0) + 120;
|
|
res3 = 80 - Sin(theta + 1, r8);
|
|
res4 = Cos(theta + 1, r8) + 120;
|
|
if ((res1 >= 0 || res3 >= 0) && (res1 <= 159 || res3 <= 159))
|
|
{
|
|
if (res1 < 0)
|
|
res1 = 0;
|
|
if (res1 > 159)
|
|
res1 = 159;
|
|
if (res2 < 0)
|
|
res2 = 0;
|
|
if (res2 > 255)
|
|
res2 = 255;
|
|
if (res3 < 0)
|
|
res3 = 0;
|
|
if (res3 > 159)
|
|
res3 = 159;
|
|
if (res4 < 0)
|
|
res4 = 0;
|
|
if (res4 > 255)
|
|
res4 = 255;
|
|
diff = res3 - res1;
|
|
if (theta - 64 >= 0)
|
|
{
|
|
gScanlineEffectRegBuffers[1][res1 + 320] = res2;
|
|
if (diff)
|
|
{
|
|
s16 diff2 = res4 - res2;
|
|
|
|
if (diff2 < -1 && res2 > 1)
|
|
--res2;
|
|
else if (diff2 > 1 && res2 <= 254)
|
|
++res2;
|
|
// PROBLEM #2:
|
|
// (around line 300 in ASM)
|
|
// The current version matched the control flow,
|
|
// but it looks too weird and some shift doesn't match
|
|
|
|
// functional equivalent:
|
|
// for (j = diff; j < 0; ++j)
|
|
// gScanlineEffectRegBuffers[1][res1 + j + 480] = res2;
|
|
// for (j = diff; j > 0; --j)
|
|
// gScanlineEffectRegBuffers[1][res1 + j + 480] = res2;
|
|
if ((j = diff) < 0)
|
|
do
|
|
gScanlineEffectRegBuffers[1][res1 + j + 320] = res2;
|
|
while (++j < 0);
|
|
else
|
|
while (j > 0)
|
|
{
|
|
gScanlineEffectRegBuffers[1][res1 + j + 320] = res2;
|
|
++j;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
gScanlineEffectRegBuffers[1][res1 + 480] = res2;
|
|
if (diff)
|
|
{
|
|
s16 diff2 = res4 - res2;
|
|
|
|
if (diff2 < -1 && res2 > 1)
|
|
--res2;
|
|
else if (diff2 > 1 && res2 <= 254)
|
|
++res2;
|
|
// same as PROBLEM #2
|
|
for (j = diff; j < 0; ++j)
|
|
gScanlineEffectRegBuffers[1][res1 + j + 480] = res2;
|
|
for (j = diff; j > 0; --j)
|
|
gScanlineEffectRegBuffers[1][res1 + j + 480] = res2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// PROBLEM #3: We need (a2 << 16) & 0x30000 here.
|
|
// Is it because the programmer declared a s32 var to
|
|
// hold the value of a2 and then cast the result to s16?
|
|
// Currently I have to write it explicitly.
|
|
// (around line 460 in ASM)
|
|
if (!a3 || !((a2 << 16) & 0x30000))
|
|
{
|
|
for (i = 0; i < 160; ++i)
|
|
gScanlineEffectRegBuffers[1][i * 2 + a3] = (gScanlineEffectRegBuffers[1][i + 320] << 8) | gScanlineEffectRegBuffers[1][i + 480];
|
|
}
|
|
else
|
|
{
|
|
s16 res = Sin(a2 * 16, a1 + a2 * 2);
|
|
|
|
switch (a2 / 4)
|
|
{
|
|
case 0:
|
|
if (res > 80)
|
|
res = 80;
|
|
// PROBLEM #4:
|
|
// (around line 550 in ASM)
|
|
// Case 0-3 are very similar, so it's very likely
|
|
// that they have the same problem.
|
|
// The code is definitely functional equivalent,
|
|
// but the vanilla game used some extra shifts and
|
|
// used unsigned comparison. Another difference is
|
|
// that I can't figure out a way to make gUnknown_83FA444[a2]
|
|
// happen outside the loop body.
|
|
// It seems that sTransitionStructPtr->data[2] need
|
|
// to be used in the first statement so that the
|
|
// struct pointer sTransitionStructPtr will be loaded
|
|
// early enough.
|
|
//
|
|
// Logically the generated code is following if + do-while structure.
|
|
// But it seems that it can only make the situation even worse.
|
|
/*
|
|
i = res;
|
|
if (i > 0)
|
|
{
|
|
// This happens before loop body.
|
|
s16 unk = gUnknown_83FA444[a2];
|
|
|
|
do
|
|
{
|
|
sTransitionStructPtr->data[2] = ((i * unk) >> 8) + 120;
|
|
if (sTransitionStructPtr->data[2] <= 255)
|
|
{
|
|
sTransitionStructPtr->bg123HOfs = 400 - i;
|
|
sTransitionStructPtr->data[10] = gScanlineEffectRegBuffers[1][400 - i];
|
|
if (gScanlineEffectRegBuffers[1][560 - i] < sTransitionStructPtr->data[2])
|
|
gScanlineEffectRegBuffers[1][560 - i] = 120;
|
|
else if (gScanlineEffectRegBuffers[1][400 - i] < sTransitionStructPtr->data[2])
|
|
gScanlineEffectRegBuffers[1][400 - i] = sTransitionStructPtr->data[2];
|
|
}
|
|
}
|
|
while (--i > 0);
|
|
}
|
|
*/
|
|
for (i = res; i > 0; --i)
|
|
{
|
|
sTransitionStructPtr->data[2] = ((i * gUnknown_83FA444[a2]) >> 8) + 120;
|
|
if (sTransitionStructPtr->data[2] <= 255)
|
|
{
|
|
sTransitionStructPtr->bg123HOfs = 400 - i;
|
|
sTransitionStructPtr->data[10] = gScanlineEffectRegBuffers[1][400 - i];
|
|
if (gScanlineEffectRegBuffers[1][560 - i] < sTransitionStructPtr->data[2])
|
|
gScanlineEffectRegBuffers[1][560 - i] = 120;
|
|
else if (gScanlineEffectRegBuffers[1][400 - i] < sTransitionStructPtr->data[2])
|
|
gScanlineEffectRegBuffers[1][400 - i] = sTransitionStructPtr->data[2];
|
|
}
|
|
}
|
|
break;
|
|
case 1:
|
|
if (res > 80)
|
|
res = 80;
|
|
// same as PROBLEM #4
|
|
for (i = res; i > 0; --i)
|
|
{
|
|
s16 unkVal;
|
|
|
|
sTransitionStructPtr->data[2] = ((i * gUnknown_83FA444[a2]) >> 8) + 120;
|
|
if (sTransitionStructPtr->data[2] <= 255)
|
|
{
|
|
sTransitionStructPtr->bg123HOfs = 400 - i;
|
|
sTransitionStructPtr->data[10] = gScanlineEffectRegBuffers[1][400 - i];
|
|
if (gScanlineEffectRegBuffers[1][400 - i] < sTransitionStructPtr->data[2])
|
|
gScanlineEffectRegBuffers[1][400 - i] = sTransitionStructPtr->data[2];
|
|
}
|
|
}
|
|
break;
|
|
case 2:
|
|
if (res < -79)
|
|
res = -79;
|
|
// same as PROBLEM #4
|
|
for (i = res; i <= 0; ++i)
|
|
{
|
|
sTransitionStructPtr->data[2] = ((i * gUnknown_83FA444[a2]) >> 8) + 120;
|
|
if (sTransitionStructPtr->data[2] <= 255)
|
|
{
|
|
sTransitionStructPtr->bg123HOfs = 560 - i;
|
|
sTransitionStructPtr->data[10] = gScanlineEffectRegBuffers[1][560 - i];
|
|
if (gScanlineEffectRegBuffers[1][400 - i] >= sTransitionStructPtr->data[2])
|
|
gScanlineEffectRegBuffers[1][400 - i] = 120;
|
|
else if (gScanlineEffectRegBuffers[1][560 - i] > sTransitionStructPtr->data[2])
|
|
gScanlineEffectRegBuffers[1][560 - i] = sTransitionStructPtr->data[2];
|
|
}
|
|
}
|
|
break;
|
|
case 3:
|
|
if (res < -79)
|
|
res = -79;
|
|
// same as PROBLEM #4
|
|
for (i = res; i <= 0; ++i)
|
|
{
|
|
sTransitionStructPtr->data[2] = ((i * gUnknown_83FA444[a2]) >> 8) + 120;
|
|
if (sTransitionStructPtr->data[2] <= 255)
|
|
{
|
|
sTransitionStructPtr->bg123HOfs = 560 - i;
|
|
sTransitionStructPtr->data[10] = gScanlineEffectRegBuffers[1][560 - i];
|
|
if (gScanlineEffectRegBuffers[1][560 - i] > sTransitionStructPtr->data[2])
|
|
gScanlineEffectRegBuffers[1][560 - i] = sTransitionStructPtr->data[2];
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
for (i = 0; i < 160; ++i)
|
|
gScanlineEffectRegBuffers[1][2 * i + a3] = (gScanlineEffectRegBuffers[1][i + 320] << 8) | gScanlineEffectRegBuffers[1][i + 480];
|
|
}
|
|
}
|
|
#else
|
|
NAKED
|
|
static void sub_80D1F64(s16 a1, s16 a2, u8 a3)
|
|
{
|
|
asm_unified("\n\
|
|
push {r4-r7,lr}\n\
|
|
mov r7, r10\n\
|
|
mov r6, r9\n\
|
|
mov r5, r8\n\
|
|
push {r5-r7}\n\
|
|
sub sp, 0x14\n\
|
|
lsls r0, 16\n\
|
|
lsrs r0, 16\n\
|
|
str r0, [sp]\n\
|
|
lsls r1, 16\n\
|
|
lsrs r5, r1, 16\n\
|
|
lsls r2, 24\n\
|
|
lsrs r2, 24\n\
|
|
str r2, [sp, 0x4]\n\
|
|
movs r0, 0\n\
|
|
mov r10, r0\n\
|
|
movs r1, 0xA0\n\
|
|
lsls r1, 17\n\
|
|
ldr r4, _080D1FD8 @ =gScanlineEffectRegBuffers + 0x780\n\
|
|
ldr r3, _080D1FDC @ =0x000003bf\n\
|
|
movs r2, 0x78\n\
|
|
_080D1F8E:\n\
|
|
asrs r0, r1, 16\n\
|
|
lsls r1, r0, 1\n\
|
|
adds r1, r4\n\
|
|
strh r2, [r1]\n\
|
|
adds r0, 0x1\n\
|
|
lsls r1, r0, 16\n\
|
|
asrs r0, r1, 16\n\
|
|
cmp r0, r3\n\
|
|
ble _080D1F8E\n\
|
|
lsls r0, r5, 16\n\
|
|
movs r1, 0\n\
|
|
mov r9, r1\n\
|
|
str r0, [sp, 0xC]\n\
|
|
cmp r0, 0\n\
|
|
bgt _080D1FAE\n\
|
|
b _080D221A\n\
|
|
_080D1FAE:\n\
|
|
mov r3, r10\n\
|
|
lsrs r2, r3, 3\n\
|
|
ldr r4, [sp]\n\
|
|
adds r0, r2, r4\n\
|
|
lsls r0, 16\n\
|
|
lsrs r3, r0, 16\n\
|
|
mov r0, r10\n\
|
|
adds r0, 0x1\n\
|
|
asrs r1, r0, 3\n\
|
|
str r0, [sp, 0x8]\n\
|
|
cmp r2, r1\n\
|
|
beq _080D1FE0\n\
|
|
lsls r1, r3, 16\n\
|
|
movs r6, 0x80\n\
|
|
lsls r6, 9\n\
|
|
adds r0, r1, r6\n\
|
|
lsrs r0, 16\n\
|
|
mov r8, r0\n\
|
|
adds r0, r1, 0\n\
|
|
b _080D1FE6\n\
|
|
.align 2, 0\n\
|
|
_080D1FD8: .4byte gScanlineEffectRegBuffers + 0x780\n\
|
|
_080D1FDC: .4byte 0x000003bf\n\
|
|
_080D1FE0:\n\
|
|
lsls r0, r3, 16\n\
|
|
lsrs r1, r0, 16\n\
|
|
mov r8, r1\n\
|
|
_080D1FE6:\n\
|
|
asrs r4, r0, 16\n\
|
|
mov r0, r10\n\
|
|
adds r1, r4, 0\n\
|
|
bl Sin\n\
|
|
movs r5, 0x50\n\
|
|
subs r0, r5, r0\n\
|
|
lsls r0, 16\n\
|
|
lsrs r2, r0, 16\n\
|
|
mov r0, r10\n\
|
|
adds r1, r4, 0\n\
|
|
str r2, [sp, 0x10]\n\
|
|
bl Cos\n\
|
|
adds r0, 0x78\n\
|
|
lsls r0, 16\n\
|
|
lsrs r7, r0, 16\n\
|
|
ldr r6, [sp, 0x8]\n\
|
|
mov r3, r8\n\
|
|
lsls r4, r3, 16\n\
|
|
asrs r4, 16\n\
|
|
adds r0, r6, 0\n\
|
|
adds r1, r4, 0\n\
|
|
bl Sin\n\
|
|
subs r5, r0\n\
|
|
lsls r5, 16\n\
|
|
lsrs r5, 16\n\
|
|
adds r0, r6, 0\n\
|
|
adds r1, r4, 0\n\
|
|
bl Cos\n\
|
|
adds r0, 0x78\n\
|
|
lsls r0, 16\n\
|
|
lsrs r3, r0, 16\n\
|
|
ldr r2, [sp, 0x10]\n\
|
|
lsls r0, r2, 16\n\
|
|
asrs r1, r0, 16\n\
|
|
cmp r1, 0\n\
|
|
bge _080D203E\n\
|
|
lsls r0, r5, 16\n\
|
|
cmp r0, 0\n\
|
|
bge _080D203E\n\
|
|
b _080D21F8\n\
|
|
_080D203E:\n\
|
|
cmp r1, 0x9F\n\
|
|
ble _080D204C\n\
|
|
lsls r0, r5, 16\n\
|
|
asrs r0, 16\n\
|
|
cmp r0, 0x9F\n\
|
|
ble _080D204C\n\
|
|
b _080D21F8\n\
|
|
_080D204C:\n\
|
|
cmp r1, 0\n\
|
|
bge _080D2052\n\
|
|
movs r2, 0\n\
|
|
_080D2052:\n\
|
|
lsls r0, r2, 16\n\
|
|
asrs r0, 16\n\
|
|
cmp r0, 0x9F\n\
|
|
ble _080D205C\n\
|
|
movs r2, 0x9F\n\
|
|
_080D205C:\n\
|
|
lsls r0, r7, 16\n\
|
|
cmp r0, 0\n\
|
|
bge _080D2064\n\
|
|
movs r7, 0\n\
|
|
_080D2064:\n\
|
|
lsls r0, r7, 16\n\
|
|
asrs r0, 16\n\
|
|
cmp r0, 0xFF\n\
|
|
ble _080D206E\n\
|
|
movs r7, 0xFF\n\
|
|
_080D206E:\n\
|
|
lsls r0, r5, 16\n\
|
|
cmp r0, 0\n\
|
|
bge _080D2076\n\
|
|
movs r5, 0\n\
|
|
_080D2076:\n\
|
|
lsls r0, r5, 16\n\
|
|
asrs r0, 16\n\
|
|
cmp r0, 0x9F\n\
|
|
ble _080D2080\n\
|
|
movs r5, 0x9F\n\
|
|
_080D2080:\n\
|
|
lsls r0, r3, 16\n\
|
|
cmp r0, 0\n\
|
|
bge _080D2088\n\
|
|
movs r3, 0\n\
|
|
_080D2088:\n\
|
|
lsls r0, r3, 16\n\
|
|
asrs r0, 16\n\
|
|
cmp r0, 0xFF\n\
|
|
ble _080D2092\n\
|
|
movs r3, 0xFF\n\
|
|
_080D2092:\n\
|
|
lsls r0, r5, 16\n\
|
|
asrs r0, 16\n\
|
|
lsls r1, r2, 16\n\
|
|
asrs r2, r1, 16\n\
|
|
subs r0, r2\n\
|
|
lsls r0, 16\n\
|
|
lsrs r5, r0, 16\n\
|
|
mov r0, r10\n\
|
|
subs r0, 0x40\n\
|
|
lsls r0, 24\n\
|
|
adds r6, r1, 0\n\
|
|
cmp r0, 0\n\
|
|
blt _080D2158\n\
|
|
movs r4, 0xA0\n\
|
|
lsls r4, 1\n\
|
|
adds r0, r2, r4\n\
|
|
lsls r0, 1\n\
|
|
ldr r1, _080D20E8 @ =gScanlineEffectRegBuffers + 0x780\n\
|
|
adds r0, r1\n\
|
|
strh r7, [r0]\n\
|
|
lsls r0, r5, 16\n\
|
|
adds r4, r0, 0\n\
|
|
cmp r4, 0\n\
|
|
bne _080D20C4\n\
|
|
b _080D21F8\n\
|
|
_080D20C4:\n\
|
|
lsls r0, r3, 16\n\
|
|
asrs r0, 16\n\
|
|
lsls r1, r7, 16\n\
|
|
asrs r2, r1, 16\n\
|
|
subs r0, r2\n\
|
|
lsls r0, 16\n\
|
|
lsrs r3, r0, 16\n\
|
|
asrs r0, 16\n\
|
|
mov r8, r0\n\
|
|
movs r0, 0x1\n\
|
|
negs r0, r0\n\
|
|
cmp r8, r0\n\
|
|
bge _080D20EC\n\
|
|
cmp r2, 0x1\n\
|
|
ble _080D20EC\n\
|
|
subs r0, r2, 0x1\n\
|
|
b _080D20FC\n\
|
|
.align 2, 0\n\
|
|
_080D20E8: .4byte gScanlineEffectRegBuffers + 0x780\n\
|
|
_080D20EC:\n\
|
|
lsls r0, r3, 16\n\
|
|
asrs r0, 16\n\
|
|
cmp r0, 0x1\n\
|
|
ble _080D2100\n\
|
|
asrs r0, r1, 16\n\
|
|
cmp r0, 0xFE\n\
|
|
bgt _080D2100\n\
|
|
adds r0, 0x1\n\
|
|
_080D20FC:\n\
|
|
lsls r0, 16\n\
|
|
lsrs r7, r0, 16\n\
|
|
_080D2100:\n\
|
|
adds r0, r4, 0\n\
|
|
asrs r1, r0, 16\n\
|
|
cmp r1, 0\n\
|
|
bge _080D212C\n\
|
|
asrs r2, r6, 16\n\
|
|
ldr r3, _080D2128 @ =gScanlineEffectRegBuffers + 0x780\n\
|
|
_080D210C:\n\
|
|
asrs r1, r0, 16\n\
|
|
adds r0, r2, r1\n\
|
|
movs r4, 0xA0\n\
|
|
lsls r4, 1\n\
|
|
adds r0, r4\n\
|
|
lsls r0, 1\n\
|
|
adds r0, r3\n\
|
|
strh r7, [r0]\n\
|
|
adds r1, 0x1\n\
|
|
lsls r0, r1, 16\n\
|
|
cmp r0, 0\n\
|
|
blt _080D210C\n\
|
|
b _080D21F8\n\
|
|
.align 2, 0\n\
|
|
_080D2128: .4byte gScanlineEffectRegBuffers + 0x780\n\
|
|
_080D212C:\n\
|
|
cmp r1, 0\n\
|
|
ble _080D21F8\n\
|
|
asrs r2, r6, 16\n\
|
|
ldr r3, _080D2154 @ =gScanlineEffectRegBuffers + 0x780\n\
|
|
_080D2134:\n\
|
|
lsls r1, r5, 16\n\
|
|
asrs r1, 16\n\
|
|
adds r0, r2, r1\n\
|
|
movs r6, 0xA0\n\
|
|
lsls r6, 1\n\
|
|
adds r0, r6\n\
|
|
lsls r0, 1\n\
|
|
adds r0, r3\n\
|
|
strh r7, [r0]\n\
|
|
subs r1, 0x1\n\
|
|
lsls r1, 16\n\
|
|
lsrs r5, r1, 16\n\
|
|
cmp r1, 0\n\
|
|
bgt _080D2134\n\
|
|
b _080D21F8\n\
|
|
.align 2, 0\n\
|
|
_080D2154: .4byte gScanlineEffectRegBuffers + 0x780\n\
|
|
_080D2158:\n\
|
|
movs r1, 0xF0\n\
|
|
lsls r1, 1\n\
|
|
adds r0, r2, r1\n\
|
|
lsls r0, 1\n\
|
|
ldr r2, _080D2190 @ =gScanlineEffectRegBuffers + 0x780\n\
|
|
adds r0, r2\n\
|
|
strh r7, [r0]\n\
|
|
lsls r0, r5, 16\n\
|
|
adds r4, r0, 0\n\
|
|
cmp r4, 0\n\
|
|
beq _080D21F8\n\
|
|
lsls r0, r3, 16\n\
|
|
asrs r0, 16\n\
|
|
lsls r1, r7, 16\n\
|
|
asrs r2, r1, 16\n\
|
|
subs r0, r2\n\
|
|
lsls r0, 16\n\
|
|
lsrs r3, r0, 16\n\
|
|
asrs r0, 16\n\
|
|
mov r8, r0\n\
|
|
movs r0, 0x1\n\
|
|
negs r0, r0\n\
|
|
cmp r8, r0\n\
|
|
bge _080D2194\n\
|
|
cmp r2, 0x1\n\
|
|
ble _080D2194\n\
|
|
subs r0, r2, 0x1\n\
|
|
b _080D21A4\n\
|
|
.align 2, 0\n\
|
|
_080D2190: .4byte gScanlineEffectRegBuffers + 0x780\n\
|
|
_080D2194:\n\
|
|
lsls r0, r3, 16\n\
|
|
asrs r0, 16\n\
|
|
cmp r0, 0x1\n\
|
|
ble _080D21A8\n\
|
|
asrs r0, r1, 16\n\
|
|
cmp r0, 0xFE\n\
|
|
bgt _080D21A8\n\
|
|
adds r0, 0x1\n\
|
|
_080D21A4:\n\
|
|
lsls r0, 16\n\
|
|
lsrs r7, r0, 16\n\
|
|
_080D21A8:\n\
|
|
adds r0, r4, 0\n\
|
|
asrs r1, r0, 16\n\
|
|
cmp r1, 0\n\
|
|
bge _080D21D4\n\
|
|
asrs r2, r6, 16\n\
|
|
ldr r3, _080D21D0 @ =gScanlineEffectRegBuffers + 0x780\n\
|
|
_080D21B4:\n\
|
|
asrs r1, r0, 16\n\
|
|
adds r0, r2, r1\n\
|
|
movs r4, 0xF0\n\
|
|
lsls r4, 1\n\
|
|
adds r0, r4\n\
|
|
lsls r0, 1\n\
|
|
adds r0, r3\n\
|
|
strh r7, [r0]\n\
|
|
adds r1, 0x1\n\
|
|
lsls r0, r1, 16\n\
|
|
cmp r0, 0\n\
|
|
blt _080D21B4\n\
|
|
b _080D21F8\n\
|
|
.align 2, 0\n\
|
|
_080D21D0: .4byte gScanlineEffectRegBuffers + 0x780\n\
|
|
_080D21D4:\n\
|
|
cmp r1, 0\n\
|
|
ble _080D21F8\n\
|
|
asrs r2, r6, 16\n\
|
|
ldr r3, _080D2270 @ =gScanlineEffectRegBuffers + 0x780\n\
|
|
_080D21DC:\n\
|
|
lsls r1, r5, 16\n\
|
|
asrs r1, 16\n\
|
|
adds r0, r2, r1\n\
|
|
movs r6, 0xF0\n\
|
|
lsls r6, 1\n\
|
|
adds r0, r6\n\
|
|
lsls r0, 1\n\
|
|
adds r0, r3\n\
|
|
strh r7, [r0]\n\
|
|
subs r1, 0x1\n\
|
|
lsls r1, 16\n\
|
|
lsrs r5, r1, 16\n\
|
|
cmp r1, 0\n\
|
|
bgt _080D21DC\n\
|
|
_080D21F8:\n\
|
|
mov r1, r9\n\
|
|
lsls r0, r1, 16\n\
|
|
movs r2, 0x80\n\
|
|
lsls r2, 9\n\
|
|
adds r0, r2\n\
|
|
ldr r3, [sp, 0x8]\n\
|
|
lsls r1, r3, 24\n\
|
|
lsrs r1, 24\n\
|
|
mov r10, r1\n\
|
|
lsrs r4, r0, 16\n\
|
|
mov r9, r4\n\
|
|
asrs r0, 16\n\
|
|
ldr r6, [sp, 0xC]\n\
|
|
asrs r1, r6, 12\n\
|
|
cmp r0, r1\n\
|
|
bge _080D221A\n\
|
|
b _080D1FAE\n\
|
|
_080D221A:\n\
|
|
ldr r0, [sp, 0x4]\n\
|
|
cmp r0, 0\n\
|
|
beq _080D222C\n\
|
|
movs r0, 0xC0\n\
|
|
lsls r0, 10\n\
|
|
ldr r1, [sp, 0xC]\n\
|
|
ands r0, r1\n\
|
|
cmp r0, 0\n\
|
|
bne _080D2274\n\
|
|
_080D222C:\n\
|
|
movs r2, 0\n\
|
|
mov r9, r2\n\
|
|
ldr r4, _080D2270 @ =gScanlineEffectRegBuffers + 0x780\n\
|
|
movs r5, 0xA0\n\
|
|
lsls r5, 1\n\
|
|
_080D2236:\n\
|
|
mov r3, r9\n\
|
|
lsls r1, r3, 16\n\
|
|
asrs r1, 16\n\
|
|
lsls r3, r1, 1\n\
|
|
ldr r6, [sp, 0x4]\n\
|
|
adds r3, r6\n\
|
|
lsls r3, 1\n\
|
|
adds r3, r4\n\
|
|
adds r0, r1, r5\n\
|
|
lsls r0, 1\n\
|
|
adds r0, r4\n\
|
|
ldrh r2, [r0]\n\
|
|
lsls r2, 8\n\
|
|
movs r6, 0xF0\n\
|
|
lsls r6, 1\n\
|
|
adds r0, r1, r6\n\
|
|
lsls r0, 1\n\
|
|
adds r0, r4\n\
|
|
ldrh r0, [r0]\n\
|
|
orrs r2, r0\n\
|
|
strh r2, [r3]\n\
|
|
adds r1, 0x1\n\
|
|
lsls r1, 16\n\
|
|
lsrs r0, r1, 16\n\
|
|
mov r9, r0\n\
|
|
asrs r1, 16\n\
|
|
cmp r1, 0x9F\n\
|
|
ble _080D2236\n\
|
|
b _080D251C\n\
|
|
.align 2, 0\n\
|
|
_080D2270: .4byte gScanlineEffectRegBuffers + 0x780\n\
|
|
_080D2274:\n\
|
|
ldr r1, [sp, 0xC]\n\
|
|
asrs r4, r1, 16\n\
|
|
lsls r0, r4, 20\n\
|
|
asrs r0, 16\n\
|
|
lsls r5, r4, 1\n\
|
|
ldr r2, [sp]\n\
|
|
lsls r1, r2, 16\n\
|
|
asrs r1, 16\n\
|
|
adds r1, r5\n\
|
|
lsls r1, 16\n\
|
|
asrs r1, 16\n\
|
|
bl Sin\n\
|
|
lsls r0, 16\n\
|
|
lsrs r2, r0, 16\n\
|
|
cmp r4, 0\n\
|
|
bge _080D2298\n\
|
|
adds r4, 0x3\n\
|
|
_080D2298:\n\
|
|
asrs r0, r4, 2\n\
|
|
cmp r0, 0x1\n\
|
|
beq _080D234C\n\
|
|
cmp r0, 0x1\n\
|
|
bgt _080D22A8\n\
|
|
cmp r0, 0\n\
|
|
beq _080D22B6\n\
|
|
b _080D24DA\n\
|
|
_080D22A8:\n\
|
|
cmp r0, 0x2\n\
|
|
bne _080D22AE\n\
|
|
b _080D23CC\n\
|
|
_080D22AE:\n\
|
|
cmp r0, 0x3\n\
|
|
bne _080D22B4\n\
|
|
b _080D2466\n\
|
|
_080D22B4:\n\
|
|
b _080D24DA\n\
|
|
_080D22B6:\n\
|
|
lsls r0, r2, 16\n\
|
|
asrs r0, 16\n\
|
|
cmp r0, 0x50\n\
|
|
ble _080D22C0\n\
|
|
movs r2, 0x50\n\
|
|
_080D22C0:\n\
|
|
mov r9, r2\n\
|
|
lsls r1, r2, 16\n\
|
|
cmp r1, 0\n\
|
|
bgt _080D22CA\n\
|
|
b _080D24DA\n\
|
|
_080D22CA:\n\
|
|
ldr r0, _080D2320 @ =gUnknown_83FA444\n\
|
|
adds r0, r5, r0\n\
|
|
movs r3, 0\n\
|
|
ldrsh r4, [r0, r3]\n\
|
|
ldr r6, _080D2324 @ =gScanlineEffectRegBuffers + 0x780\n\
|
|
_080D22D4:\n\
|
|
ldr r0, _080D2328 @ =sTransitionStructPtr\n\
|
|
ldr r5, [r0]\n\
|
|
asrs r2, r1, 16\n\
|
|
adds r0, r2, 0\n\
|
|
muls r0, r4\n\
|
|
asrs r0, 8\n\
|
|
adds r0, 0x78\n\
|
|
lsls r1, r0, 16\n\
|
|
lsrs r7, r1, 16\n\
|
|
strh r0, [r5, 0x28]\n\
|
|
lsls r1, r7, 16\n\
|
|
lsrs r0, r1, 16\n\
|
|
cmp r0, 0xFF\n\
|
|
bhi _080D2334\n\
|
|
movs r3, 0xC8\n\
|
|
lsls r3, 1\n\
|
|
adds r0, r3, 0\n\
|
|
subs r0, r2\n\
|
|
strh r0, [r5, 0x14]\n\
|
|
adds r0, r3, 0\n\
|
|
subs r0, r2\n\
|
|
lsls r0, 1\n\
|
|
adds r3, r0, r6\n\
|
|
ldrh r0, [r3]\n\
|
|
strh r0, [r5, 0x38]\n\
|
|
movs r0, 0x8C\n\
|
|
lsls r0, 2\n\
|
|
subs r0, r2\n\
|
|
lsls r0, 1\n\
|
|
adds r2, r0, r6\n\
|
|
ldrh r0, [r2]\n\
|
|
asrs r1, 16\n\
|
|
cmp r0, r1\n\
|
|
bge _080D232C\n\
|
|
movs r0, 0x78\n\
|
|
strh r0, [r2]\n\
|
|
b _080D2334\n\
|
|
.align 2, 0\n\
|
|
_080D2320: .4byte gUnknown_83FA444\n\
|
|
_080D2324: .4byte gScanlineEffectRegBuffers + 0x780\n\
|
|
_080D2328: .4byte sTransitionStructPtr\n\
|
|
_080D232C:\n\
|
|
ldrh r0, [r3]\n\
|
|
cmp r0, r1\n\
|
|
bge _080D2334\n\
|
|
strh r7, [r3]\n\
|
|
_080D2334:\n\
|
|
mov r1, r9\n\
|
|
lsls r0, r1, 16\n\
|
|
ldr r2, _080D2348 @ =0xffff0000\n\
|
|
adds r0, r2\n\
|
|
lsrs r0, 16\n\
|
|
mov r9, r0\n\
|
|
lsls r1, r0, 16\n\
|
|
cmp r1, 0\n\
|
|
bgt _080D22D4\n\
|
|
b _080D24DA\n\
|
|
.align 2, 0\n\
|
|
_080D2348: .4byte 0xffff0000\n\
|
|
_080D234C:\n\
|
|
lsls r0, r2, 16\n\
|
|
asrs r0, 16\n\
|
|
cmp r0, 0x50\n\
|
|
ble _080D2356\n\
|
|
movs r2, 0x50\n\
|
|
_080D2356:\n\
|
|
mov r9, r2\n\
|
|
lsls r1, r2, 16\n\
|
|
cmp r1, 0\n\
|
|
bgt _080D2360\n\
|
|
b _080D24DA\n\
|
|
_080D2360:\n\
|
|
ldr r0, _080D23BC @ =gUnknown_83FA444\n\
|
|
adds r0, r5, r0\n\
|
|
movs r3, 0\n\
|
|
ldrsh r4, [r0, r3]\n\
|
|
ldr r6, _080D23C0 @ =gScanlineEffectRegBuffers + 0x780\n\
|
|
_080D236A:\n\
|
|
ldr r0, _080D23C4 @ =sTransitionStructPtr\n\
|
|
ldr r3, [r0]\n\
|
|
asrs r2, r1, 16\n\
|
|
adds r0, r2, 0\n\
|
|
muls r0, r4\n\
|
|
asrs r0, 8\n\
|
|
adds r0, 0x78\n\
|
|
lsls r1, r0, 16\n\
|
|
lsrs r7, r1, 16\n\
|
|
strh r0, [r3, 0x28]\n\
|
|
lsls r5, r7, 16\n\
|
|
lsrs r0, r5, 16\n\
|
|
cmp r0, 0xFF\n\
|
|
bhi _080D23A6\n\
|
|
movs r1, 0xC8\n\
|
|
lsls r1, 1\n\
|
|
adds r0, r1, 0\n\
|
|
subs r0, r2\n\
|
|
strh r0, [r3, 0x14]\n\
|
|
adds r0, r1, 0\n\
|
|
subs r0, r2\n\
|
|
lsls r0, 1\n\
|
|
adds r2, r0, r6\n\
|
|
ldrh r0, [r2]\n\
|
|
strh r0, [r3, 0x38]\n\
|
|
ldrh r1, [r2]\n\
|
|
asrs r0, r5, 16\n\
|
|
cmp r1, r0\n\
|
|
bge _080D23A6\n\
|
|
strh r7, [r2]\n\
|
|
_080D23A6:\n\
|
|
mov r2, r9\n\
|
|
lsls r0, r2, 16\n\
|
|
ldr r3, _080D23C8 @ =0xffff0000\n\
|
|
adds r0, r3\n\
|
|
lsrs r0, 16\n\
|
|
mov r9, r0\n\
|
|
lsls r1, r0, 16\n\
|
|
cmp r1, 0\n\
|
|
bgt _080D236A\n\
|
|
b _080D24DA\n\
|
|
.align 2, 0\n\
|
|
_080D23BC: .4byte gUnknown_83FA444\n\
|
|
_080D23C0: .4byte gScanlineEffectRegBuffers + 0x780\n\
|
|
_080D23C4: .4byte sTransitionStructPtr\n\
|
|
_080D23C8: .4byte 0xffff0000\n\
|
|
_080D23CC:\n\
|
|
lsls r0, r2, 16\n\
|
|
asrs r0, 16\n\
|
|
movs r1, 0x4F\n\
|
|
negs r1, r1\n\
|
|
cmp r0, r1\n\
|
|
bge _080D23DA\n\
|
|
ldr r2, _080D2438 @ =0x0000ffb1\n\
|
|
_080D23DA:\n\
|
|
mov r9, r2\n\
|
|
lsls r1, r2, 16\n\
|
|
cmp r1, 0\n\
|
|
bgt _080D24DA\n\
|
|
ldr r0, _080D243C @ =gUnknown_83FA444\n\
|
|
adds r0, r5, r0\n\
|
|
movs r6, 0\n\
|
|
ldrsh r4, [r0, r6]\n\
|
|
ldr r6, _080D2440 @ =gScanlineEffectRegBuffers + 0x780\n\
|
|
_080D23EC:\n\
|
|
ldr r0, _080D2444 @ =sTransitionStructPtr\n\
|
|
ldr r5, [r0]\n\
|
|
asrs r2, r1, 16\n\
|
|
adds r0, r2, 0\n\
|
|
muls r0, r4\n\
|
|
asrs r0, 8\n\
|
|
adds r0, 0x78\n\
|
|
lsls r1, r0, 16\n\
|
|
lsrs r7, r1, 16\n\
|
|
strh r0, [r5, 0x28]\n\
|
|
lsls r1, r7, 16\n\
|
|
lsrs r0, r1, 16\n\
|
|
cmp r0, 0xFF\n\
|
|
bhi _080D2450\n\
|
|
movs r3, 0x8C\n\
|
|
lsls r3, 2\n\
|
|
adds r0, r3, 0\n\
|
|
subs r0, r2\n\
|
|
strh r0, [r5, 0x14]\n\
|
|
adds r0, r3, 0\n\
|
|
subs r0, r2\n\
|
|
lsls r0, 1\n\
|
|
adds r3, r0, r6\n\
|
|
ldrh r0, [r3]\n\
|
|
strh r0, [r5, 0x38]\n\
|
|
movs r0, 0xC8\n\
|
|
lsls r0, 1\n\
|
|
subs r0, r2\n\
|
|
lsls r0, 1\n\
|
|
adds r2, r0, r6\n\
|
|
ldrh r0, [r2]\n\
|
|
asrs r1, 16\n\
|
|
cmp r0, r1\n\
|
|
blt _080D2448\n\
|
|
movs r0, 0x78\n\
|
|
strh r0, [r2]\n\
|
|
b _080D2450\n\
|
|
.align 2, 0\n\
|
|
_080D2438: .4byte 0x0000ffb1\n\
|
|
_080D243C: .4byte gUnknown_83FA444\n\
|
|
_080D2440: .4byte gScanlineEffectRegBuffers + 0x780\n\
|
|
_080D2444: .4byte sTransitionStructPtr\n\
|
|
_080D2448:\n\
|
|
ldrh r0, [r3]\n\
|
|
cmp r0, r1\n\
|
|
ble _080D2450\n\
|
|
strh r7, [r3]\n\
|
|
_080D2450:\n\
|
|
mov r1, r9\n\
|
|
lsls r0, r1, 16\n\
|
|
movs r2, 0x80\n\
|
|
lsls r2, 9\n\
|
|
adds r0, r2\n\
|
|
lsrs r0, 16\n\
|
|
mov r9, r0\n\
|
|
lsls r1, r0, 16\n\
|
|
cmp r1, 0\n\
|
|
ble _080D23EC\n\
|
|
b _080D24DA\n\
|
|
_080D2466:\n\
|
|
lsls r0, r2, 16\n\
|
|
asrs r0, 16\n\
|
|
movs r1, 0x4F\n\
|
|
negs r1, r1\n\
|
|
cmp r0, r1\n\
|
|
bge _080D2474\n\
|
|
ldr r2, _080D252C @ =0x0000ffb1\n\
|
|
_080D2474:\n\
|
|
mov r9, r2\n\
|
|
lsls r1, r2, 16\n\
|
|
cmp r1, 0\n\
|
|
bgt _080D24DA\n\
|
|
ldr r0, _080D2530 @ =gUnknown_83FA444\n\
|
|
adds r0, r5, r0\n\
|
|
movs r3, 0\n\
|
|
ldrsh r4, [r0, r3]\n\
|
|
ldr r6, _080D2534 @ =sTransitionStructPtr\n\
|
|
mov r8, r6\n\
|
|
ldr r6, _080D2538 @ =gScanlineEffectRegBuffers + 0x780\n\
|
|
_080D248A:\n\
|
|
mov r0, r8\n\
|
|
ldr r3, [r0]\n\
|
|
asrs r2, r1, 16\n\
|
|
adds r0, r2, 0\n\
|
|
muls r0, r4\n\
|
|
asrs r0, 8\n\
|
|
adds r0, 0x78\n\
|
|
lsls r1, r0, 16\n\
|
|
lsrs r7, r1, 16\n\
|
|
strh r0, [r3, 0x28]\n\
|
|
lsls r5, r7, 16\n\
|
|
lsrs r0, r5, 16\n\
|
|
cmp r0, 0xFF\n\
|
|
bhi _080D24C6\n\
|
|
movs r1, 0x8C\n\
|
|
lsls r1, 2\n\
|
|
adds r0, r1, 0\n\
|
|
subs r0, r2\n\
|
|
strh r0, [r3, 0x14]\n\
|
|
adds r0, r1, 0\n\
|
|
subs r0, r2\n\
|
|
lsls r0, 1\n\
|
|
adds r2, r0, r6\n\
|
|
ldrh r0, [r2]\n\
|
|
strh r0, [r3, 0x38]\n\
|
|
ldrh r1, [r2]\n\
|
|
asrs r0, r5, 16\n\
|
|
cmp r1, r0\n\
|
|
ble _080D24C6\n\
|
|
strh r7, [r2]\n\
|
|
_080D24C6:\n\
|
|
mov r2, r9\n\
|
|
lsls r0, r2, 16\n\
|
|
movs r3, 0x80\n\
|
|
lsls r3, 9\n\
|
|
adds r0, r3\n\
|
|
lsrs r0, 16\n\
|
|
mov r9, r0\n\
|
|
lsls r1, r0, 16\n\
|
|
cmp r1, 0\n\
|
|
ble _080D248A\n\
|
|
_080D24DA:\n\
|
|
movs r4, 0\n\
|
|
mov r9, r4\n\
|
|
ldr r4, _080D2538 @ =gScanlineEffectRegBuffers + 0x780\n\
|
|
movs r5, 0xA0\n\
|
|
lsls r5, 1\n\
|
|
_080D24E4:\n\
|
|
mov r6, r9\n\
|
|
lsls r1, r6, 16\n\
|
|
asrs r1, 16\n\
|
|
lsls r3, r1, 1\n\
|
|
ldr r0, [sp, 0x4]\n\
|
|
adds r3, r0\n\
|
|
lsls r3, 1\n\
|
|
adds r3, r4\n\
|
|
adds r0, r1, r5\n\
|
|
lsls r0, 1\n\
|
|
adds r0, r4\n\
|
|
ldrh r2, [r0]\n\
|
|
lsls r2, 8\n\
|
|
movs r6, 0xF0\n\
|
|
lsls r6, 1\n\
|
|
adds r0, r1, r6\n\
|
|
lsls r0, 1\n\
|
|
adds r0, r4\n\
|
|
ldrh r0, [r0]\n\
|
|
orrs r2, r0\n\
|
|
strh r2, [r3]\n\
|
|
adds r1, 0x1\n\
|
|
lsls r1, 16\n\
|
|
lsrs r0, r1, 16\n\
|
|
mov r9, r0\n\
|
|
asrs r1, 16\n\
|
|
cmp r1, 0x9F\n\
|
|
ble _080D24E4\n\
|
|
_080D251C:\n\
|
|
add sp, 0x14\n\
|
|
pop {r3-r5}\n\
|
|
mov r8, r3\n\
|
|
mov r9, r4\n\
|
|
mov r10, r5\n\
|
|
pop {r4-r7}\n\
|
|
pop {r0}\n\
|
|
bx r0\n\
|
|
.align 2, 0\n\
|
|
_080D252C: .4byte 0x0000ffb1\n\
|
|
_080D2530: .4byte gUnknown_83FA444\n\
|
|
_080D2534: .4byte sTransitionStructPtr\n\
|
|
_080D2538: .4byte gScanlineEffectRegBuffers + 0x780\n\
|
|
");
|
|
}
|
|
#endif
|
|
|
|
static bool8 BT_Phase2AntiClockwiseSpiral_Init(struct Task *task)
|
|
{
|
|
BT_InitCtrlBlk();
|
|
ScanlineEffect_Clear();
|
|
sTransitionStructPtr->winIn = 0;
|
|
sTransitionStructPtr->winOut = WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR;
|
|
sTransitionStructPtr->win0H = WIN_RANGE(0x78, 0x78);
|
|
sTransitionStructPtr->win0V = WIN_RANGE(0x30, 0x70);
|
|
sTransitionStructPtr->win1V = WIN_RANGE(0x10, 0x90);
|
|
sTransitionStructPtr->counter = 0;
|
|
sub_80D1F64(0, 0, FALSE);
|
|
sub_80D1F64(0, 0, TRUE);
|
|
DmaCopy16(3, gScanlineEffectRegBuffers[1], gScanlineEffectRegBuffers[0], 640);
|
|
SetVBlankCallback(VBCB_BT_Phase2AntiClockwiseBlackFade);
|
|
++task->tState;
|
|
task->data[1] = 0;
|
|
task->data[2] = 0;
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 BT_Phase2AntiClockwiseSpiral_Update(struct Task *task)
|
|
{
|
|
s16 v0, v1;
|
|
|
|
sub_80D1F64(task->data[2], task->data[1], TRUE);
|
|
sTransitionStructPtr->vblankDma |= TRUE;
|
|
if (++task->data[1] == 17)
|
|
{
|
|
sub_80D1F64(task->data[2], 16, FALSE);
|
|
v0 = 48 - task->data[2];
|
|
if (v0 < 0)
|
|
v0 = 0;
|
|
v1 = task->data[2] + 112;
|
|
if (v1 > 255)
|
|
v1 = 255;
|
|
sTransitionStructPtr->win0V = v0 | v1;
|
|
task->data[2] += 32;
|
|
task->data[1] = 0;
|
|
sub_80D1F64(task->data[2], 0, TRUE);
|
|
v0 = 48 - task->data[2];
|
|
if (v0 < 0)
|
|
v0 = 0;
|
|
v1 = task->data[2] + 112;
|
|
if (v1 > 255)
|
|
v1 = 255;
|
|
sTransitionStructPtr->win1V = v0 | v1;
|
|
sTransitionStructPtr->vblankDma |= TRUE;
|
|
if (task->data[2] > 159)
|
|
{
|
|
sTransitionStructPtr->counter = 1;
|
|
BT_BlendPalettesToBlack();
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static void VBCB_BT_Phase2AntiClockwiseBlackFade(void)
|
|
{
|
|
DmaStop(0);
|
|
BT_VBSyncOamAndPltt();
|
|
if (sTransitionStructPtr->counter)
|
|
{
|
|
DestroyTask(FindTaskIdByFunc(BT_Phase2AntiClockwiseSpiral));
|
|
}
|
|
else
|
|
{
|
|
if (sTransitionStructPtr->vblankDma)
|
|
{
|
|
DmaCopy16(3, gScanlineEffectRegBuffers[1], gScanlineEffectRegBuffers[0], 640);
|
|
sTransitionStructPtr->vblankDma = FALSE;
|
|
}
|
|
SetGpuReg(REG_OFFSET_WININ, sTransitionStructPtr->winIn);
|
|
SetGpuReg(REG_OFFSET_WINOUT, sTransitionStructPtr->winOut);
|
|
SetGpuReg(REG_OFFSET_WIN0V, sTransitionStructPtr->win0V);
|
|
SetGpuReg(REG_OFFSET_WIN1V, sTransitionStructPtr->win1V);
|
|
SetGpuReg(REG_OFFSET_WIN0H, gScanlineEffectRegBuffers[0][0]);
|
|
SetGpuReg(REG_OFFSET_WIN1H, gScanlineEffectRegBuffers[0][1]);
|
|
DmaSet(0, gScanlineEffectRegBuffers[0], ®_WIN0H, ((DMA_ENABLE | DMA_START_HBLANK | DMA_REPEAT | DMA_32BIT | DMA_SRC_INC | DMA_DEST_FIXED) << 16) | 1);
|
|
}
|
|
}
|
|
|
|
#define tTheta data[1]
|
|
#define tbg0HOfsOpponent data[2]
|
|
#define tbg0HOfsPlayer data[3]
|
|
#define tCounter data[3]
|
|
#define tHalfBandwidth data[4]
|
|
#define tOpponentSpriteId data[13]
|
|
#define tPlayerSpriteId data[14]
|
|
#define tWhichMugshot data[15]
|
|
|
|
#define spState data[0]
|
|
#define spSpeed data[1]
|
|
#define spAbsAcc data[2]
|
|
#define sphasSlideFinished data[6]
|
|
#define spOpponentOrPlayer data[7]
|
|
|
|
static void BT_Phase2StartLoreleiMugshot(u8 taskId)
|
|
{
|
|
gTasks[taskId].tWhichMugshot = MUGSHOT_LORELEI;
|
|
BT_Phase2Mugshot(taskId);
|
|
}
|
|
|
|
static void BT_Phase2StartBrunoMugshot(u8 taskId)
|
|
{
|
|
gTasks[taskId].tWhichMugshot = MUGSHOT_BRUNO;
|
|
BT_Phase2Mugshot(taskId);
|
|
}
|
|
|
|
static void BT_Phase2StartAgathaMugshot(u8 taskId)
|
|
{
|
|
gTasks[taskId].tWhichMugshot = MUGSHOT_AGATHA;
|
|
BT_Phase2Mugshot(taskId);
|
|
}
|
|
|
|
static void BT_Phase2StartLanceMugshot(u8 taskId)
|
|
{
|
|
gTasks[taskId].tWhichMugshot = MUGSHOT_LANCE;
|
|
BT_Phase2Mugshot(taskId);
|
|
}
|
|
|
|
static void BT_Phase2StartBlueMugshot(u8 taskId)
|
|
{
|
|
gTasks[taskId].tWhichMugshot = MUGSHOT_BLUE;
|
|
BT_Phase2Mugshot(taskId);
|
|
}
|
|
|
|
static void BT_Phase2Mugshot(u8 taskId)
|
|
{
|
|
while (sBT_Phase2MugshotFuncs[gTasks[taskId].tState](&gTasks[taskId]));
|
|
}
|
|
|
|
static bool8 BT_Phase2Mugshot_Init(struct Task *task)
|
|
{
|
|
u8 i;
|
|
|
|
BT_InitCtrlBlk();
|
|
ScanlineEffect_Clear();
|
|
BT_Phase2Mugshots_CreateSprites(task);
|
|
task->tTheta = 0;
|
|
task->tbg0HOfsOpponent = 1;
|
|
task->tbg0HOfsPlayer = 239;
|
|
sTransitionStructPtr->winIn = WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR;
|
|
sTransitionStructPtr->winOut = WININ_WIN0_BG1 | WININ_WIN0_BG2 | WININ_WIN0_BG3 | WININ_WIN0_OBJ | WININ_WIN0_CLR;
|
|
sTransitionStructPtr->win0V = WIN_RANGE(0, 0xA0);
|
|
for (i = 0; i < 160; ++i)
|
|
gScanlineEffectRegBuffers[1][i] = WIN_RANGE(0xF0, 0xF1);
|
|
SetVBlankCallback(VBCB_BT_Phase2Mugshot1_Slide);
|
|
++task->tState;
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 BT_Phase2Mugshot_LoadGfx(struct Task *task)
|
|
{
|
|
s16 i, j;
|
|
u16 *tilemapAddr, *tilesetAddr;
|
|
const u16 *mugshotsMap = sVsBarTilemap;
|
|
|
|
BT_GetBg0TilemapAndTilesetBase(&tilemapAddr, &tilesetAddr);
|
|
CpuSet(sVsBarTileset, tilesetAddr, 0xF0);
|
|
LoadPalette(sVsBarOpponentPalettes[task->tWhichMugshot], 0xF0, 0x20);
|
|
LoadPalette(sVsBarPlayerPalettes[gSaveBlock2Ptr->playerGender], 0xFA, 0xC);
|
|
for (i = 0; i < 20; ++i)
|
|
for (j = 0; j < 32; ++j, ++mugshotsMap)
|
|
tilemapAddr[i * 32 + j] = *mugshotsMap | 0xF000; // use palette #15
|
|
EnableInterrupts(INTR_FLAG_HBLANK);
|
|
SetHBlankCallback(HBCB_BT_Phase2Mugshot);
|
|
++task->tState;
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 BT_Phase2Mugshot_VsBarsSlideIn(struct Task *task)
|
|
{
|
|
u8 i, theta;
|
|
u16 *winVal;
|
|
s16 value;
|
|
s32 mergedBg0hOfs;
|
|
|
|
sTransitionStructPtr->vblankDma = FALSE;
|
|
|
|
winVal = gScanlineEffectRegBuffers[0];
|
|
theta = task->tTheta;
|
|
task->tTheta += 0x10;
|
|
for (i = 0; i < 80; ++i, ++winVal, theta += 0x10)
|
|
{
|
|
value = task->tbg0HOfsOpponent + Sin(theta, 0x10);
|
|
if (value < 0)
|
|
value = 1;
|
|
if (value > 0xF0)
|
|
value = 0xF0;
|
|
*winVal = value;
|
|
}
|
|
for (; i < 160; ++i, ++winVal, theta += 0x10)
|
|
{
|
|
value = task->tCounter - Sin(theta, 0x10);
|
|
if (value < 0)
|
|
value = 0;
|
|
if (value > 0xEF)
|
|
value = 0xEF;
|
|
*winVal = (value << 8) | (0xF0);
|
|
}
|
|
task->tbg0HOfsOpponent += 8;
|
|
task->tCounter -= 8;
|
|
if (task->tbg0HOfsOpponent > 0xF0)
|
|
task->tbg0HOfsOpponent = 0xF0;
|
|
if (task->tCounter < 0)
|
|
task->tCounter = 0;
|
|
mergedBg0hOfs = *(s32 *)(&task->tbg0HOfsOpponent);
|
|
if (mergedBg0hOfs == 0x00F0)
|
|
++task->tState;
|
|
sTransitionStructPtr->bg0HOfsOpponent -= 8;
|
|
sTransitionStructPtr->bg0HOfsPlayer += 8;
|
|
++sTransitionStructPtr->vblankDma;
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 BT_Phase2Mugshot_StartSpriteSlide(struct Task *task)
|
|
{
|
|
u8 i;
|
|
u16 *winVal;
|
|
|
|
sTransitionStructPtr->vblankDma = FALSE;
|
|
for (i = 0, winVal = gScanlineEffectRegBuffers[0]; i < 160; ++i, ++winVal)
|
|
*winVal = 0xF0;
|
|
++task->tState;
|
|
task->tTheta = 0;
|
|
task->tbg0HOfsOpponent = 0;
|
|
task->tbg0HOfsPlayer = 0;
|
|
sTransitionStructPtr->bg0HOfsOpponent -= 8;
|
|
sTransitionStructPtr->bg0HOfsPlayer += 8;
|
|
BT_SetSpriteAsOpponentOrPlayer(task->tOpponentSpriteId, FALSE);
|
|
BT_SetSpriteAsOpponentOrPlayer(task->tPlayerSpriteId, TRUE);
|
|
BT_StartSpriteSlide(task->tOpponentSpriteId);
|
|
PlaySE(SE_BT_START);
|
|
++sTransitionStructPtr->vblankDma;
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 BT_Phase2Mugshot_WaitForOpponentInPlace(struct Task *task)
|
|
{
|
|
sTransitionStructPtr->bg0HOfsOpponent -= 8;
|
|
sTransitionStructPtr->bg0HOfsPlayer += 8;
|
|
if (BT_IsSpriteSlideFinished(task->tOpponentSpriteId))
|
|
{
|
|
++task->tState;
|
|
BT_StartSpriteSlide(task->tPlayerSpriteId);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 BT_Phase2Mugshot_WaitForPlayerInPlace(struct Task *task)
|
|
{
|
|
sTransitionStructPtr->bg0HOfsOpponent -= 8;
|
|
sTransitionStructPtr->bg0HOfsPlayer += 8;
|
|
if (BT_IsSpriteSlideFinished(task->tPlayerSpriteId))
|
|
{
|
|
sTransitionStructPtr->vblankDma = FALSE;
|
|
SetVBlankCallback(NULL);
|
|
DmaStop(0);
|
|
memset(gScanlineEffectRegBuffers[0], 0, 320);
|
|
memset(gScanlineEffectRegBuffers[1], 0, 320);
|
|
SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE(0, 0xF0));
|
|
SetGpuReg(REG_OFFSET_BLDY, 0);
|
|
++task->tState;
|
|
task->tCounter = 0;
|
|
task->tHalfBandwidth = 0;
|
|
sTransitionStructPtr->bldCnt = BLDCNT_TGT1_BG0 | BLDCNT_TGT1_BG1 | BLDCNT_TGT1_BG2 | BLDCNT_TGT1_BG3 | BLDCNT_TGT1_OBJ | BLDCNT_TGT1_BD | BLDCNT_EFFECT_LIGHTEN;
|
|
SetVBlankCallback(VBCB_BT_Phase2Mugshot2_WhiteFade);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 BT_Phase2Mugshot_ExpandWhiteBand(struct Task *task)
|
|
{
|
|
bool32 nextFunc;
|
|
|
|
sTransitionStructPtr->vblankDma = FALSE;
|
|
nextFunc = TRUE;
|
|
sTransitionStructPtr->bg0HOfsOpponent -= 8;
|
|
sTransitionStructPtr->bg0HOfsPlayer += 8;
|
|
if (task->tHalfBandwidth < 80)
|
|
task->tHalfBandwidth += 2;
|
|
if (task->tHalfBandwidth > 80)
|
|
task->tHalfBandwidth = 80;
|
|
if (++task->tCounter & 1)
|
|
{
|
|
s16 i;
|
|
|
|
for (i = 0, nextFunc = FALSE; i <= task->tHalfBandwidth; ++i)
|
|
{
|
|
s16 y1 = 80 - i;
|
|
s16 y2 = 80 + i;
|
|
|
|
if (gScanlineEffectRegBuffers[0][y1] <= 15)
|
|
{
|
|
nextFunc = TRUE;
|
|
++gScanlineEffectRegBuffers[0][y1];
|
|
}
|
|
if (gScanlineEffectRegBuffers[0][y2] <= 15)
|
|
{
|
|
nextFunc = TRUE;
|
|
++gScanlineEffectRegBuffers[0][y2];
|
|
}
|
|
}
|
|
}
|
|
if (task->tHalfBandwidth == 80 && !nextFunc)
|
|
++task->tState;
|
|
++sTransitionStructPtr->vblankDma;
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 BT_Phase2Mugshot_StartBlackFade(struct Task *task)
|
|
{
|
|
sTransitionStructPtr->vblankDma = FALSE;
|
|
BlendPalettes(0xFFFFFFFF, 0x10, RGB_WHITE);
|
|
sTransitionStructPtr->bldCnt = BLDCNT_TGT1_BG0 | BLDCNT_TGT1_BG1 | BLDCNT_TGT1_BG2 | BLDCNT_TGT1_BG3 | BLDCNT_TGT1_OBJ | BLDCNT_TGT1_BD | BLDCNT_EFFECT_DARKEN;
|
|
task->tCounter = 0;
|
|
++task->tState;
|
|
return TRUE;
|
|
}
|
|
|
|
static bool8 BT_Phase2Mugshot_WaitForBlackFade(struct Task *task)
|
|
{
|
|
sTransitionStructPtr->vblankDma = FALSE;
|
|
++task->tCounter;
|
|
memset(gScanlineEffectRegBuffers[0], task->tCounter, 320);
|
|
if (task->tCounter > 15)
|
|
++task->tState;
|
|
++sTransitionStructPtr->vblankDma;
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 BT_Phase2Mugshot_End(struct Task *task)
|
|
{
|
|
DmaStop(0);
|
|
BT_BlendPalettesToBlack();
|
|
DestroyTask(FindTaskIdByFunc(task->func));
|
|
return FALSE;
|
|
}
|
|
|
|
static void VBCB_BT_Phase2Mugshot1_Slide(void)
|
|
{
|
|
DmaStop(0);
|
|
BT_VBSyncOamAndPltt();
|
|
if (sTransitionStructPtr->vblankDma)
|
|
DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320);
|
|
SetGpuReg(REG_OFFSET_BG0VOFS, sTransitionStructPtr->bg0VOfs);
|
|
SetGpuReg(REG_OFFSET_WININ, sTransitionStructPtr->winIn);
|
|
SetGpuReg(REG_OFFSET_WINOUT, sTransitionStructPtr->winOut);
|
|
SetGpuReg(REG_OFFSET_WIN0V, sTransitionStructPtr->win0V);
|
|
DmaSet(0, gScanlineEffectRegBuffers[1], ®_WIN0H, ((DMA_ENABLE | DMA_START_HBLANK | DMA_REPEAT | DMA_SRC_INC | DMA_DEST_FIXED) << 16) | 1);
|
|
}
|
|
|
|
static void VBCB_BT_Phase2Mugshot2_WhiteFade(void)
|
|
{
|
|
DmaStop(0);
|
|
BT_VBSyncOamAndPltt();
|
|
if (sTransitionStructPtr->vblankDma)
|
|
DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320);
|
|
SetGpuReg(REG_OFFSET_BLDCNT, sTransitionStructPtr->bldCnt);
|
|
DmaSet(0, gScanlineEffectRegBuffers[1], ®_BLDY, ((DMA_ENABLE | DMA_START_HBLANK | DMA_REPEAT | DMA_SRC_INC | DMA_DEST_FIXED) << 16) | 1);
|
|
}
|
|
|
|
static void HBCB_BT_Phase2Mugshot(void)
|
|
{
|
|
if (REG_VCOUNT < 80)
|
|
REG_BG0HOFS = sTransitionStructPtr->bg0HOfsOpponent;
|
|
else
|
|
REG_BG0HOFS = sTransitionStructPtr->bg0HOfsPlayer;
|
|
}
|
|
|
|
|
|
static void BT_Phase2Mugshots_CreateSprites(struct Task *task)
|
|
{
|
|
struct Sprite *opponentSprite, *playerSprite;
|
|
s16 mugshotId;
|
|
|
|
gReservedSpritePaletteCount = 10;
|
|
mugshotId = task->tWhichMugshot;
|
|
task->tOpponentSpriteId = CreateTrainerSprite(sMugshotsTrainerPicIDsTable[mugshotId], sMugshotsOpponentCoords[mugshotId][0] - 32, sMugshotsOpponentCoords[mugshotId][1] + 42, 0, gDecompressionBuffer);
|
|
task->tPlayerSpriteId = CreateTrainerSprite(PlayerGenderToFrontTrainerPicId_Debug(gSaveBlock2Ptr->playerGender, TRUE), 272, 106, 0, gDecompressionBuffer);
|
|
gReservedSpritePaletteCount = 12;
|
|
opponentSprite = &gSprites[task->tOpponentSpriteId];
|
|
playerSprite = &gSprites[task->tPlayerSpriteId];
|
|
opponentSprite->callback = SpriteCB_BT_Phase2Mugshots;
|
|
playerSprite->callback = SpriteCB_BT_Phase2Mugshots;
|
|
opponentSprite->oam.affineMode = 3;
|
|
playerSprite->oam.affineMode = 3;
|
|
opponentSprite->oam.matrixNum = AllocOamMatrix();
|
|
playerSprite->oam.matrixNum = AllocOamMatrix();
|
|
opponentSprite->oam.shape = 1;
|
|
playerSprite->oam.shape = 1;
|
|
opponentSprite->oam.size = 3;
|
|
playerSprite->oam.size = 3;
|
|
CalcCenterToCornerVec(opponentSprite, 1, 3, 3);
|
|
CalcCenterToCornerVec(playerSprite, 1, 3, 3);
|
|
SetOamMatrixRotationScaling(opponentSprite->oam.matrixNum, sMugshotsOpponentRotationScales[mugshotId][0], sMugshotsOpponentRotationScales[mugshotId][1], 0);
|
|
SetOamMatrixRotationScaling(playerSprite->oam.matrixNum, -512, 512, 0);
|
|
}
|
|
|
|
static void SpriteCB_BT_Phase2Mugshots(struct Sprite *sprite)
|
|
{
|
|
while (sBT_Phase2MugshotSpriteFuncs[sprite->spState](sprite));
|
|
}
|
|
|
|
static bool8 BT_Phase2MugshotsSpriteFuncs_Wait(struct Sprite *sprite)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 BT_Phase2MugshotsSpriteFuncs_InitParams(struct Sprite *sprite)
|
|
{
|
|
s16 arr0[2];
|
|
s16 arr1[2];
|
|
|
|
memcpy(arr0, sMugShotSlideVelocity, sizeof(sMugShotSlideVelocity));
|
|
memcpy(arr1, sMugShotSlideDeceleration, sizeof(sMugShotSlideDeceleration));
|
|
++sprite->spState;
|
|
sprite->spSpeed = arr0[sprite->spOpponentOrPlayer];
|
|
sprite->spAbsAcc = arr1[sprite->spOpponentOrPlayer];
|
|
return TRUE;
|
|
}
|
|
|
|
static bool8 BT_Phase2MugshotsSpriteFuncs_SlideSpriteIn(struct Sprite *sprite)
|
|
{
|
|
sprite->pos1.x += sprite->spSpeed;
|
|
if (sprite->spOpponentOrPlayer && sprite->pos1.x < 133)
|
|
++sprite->spState;
|
|
else if (!sprite->spOpponentOrPlayer && sprite->pos1.x > 103)
|
|
++sprite->spState;
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 BT_Phase2MugshotsSpriteFuncs_DecelerateSprite(struct Sprite *sprite)
|
|
{
|
|
sprite->spSpeed += sprite->spAbsAcc;
|
|
sprite->pos1.x += sprite->spSpeed;
|
|
if (sprite->spSpeed == 0)
|
|
{
|
|
++sprite->spState;
|
|
sprite->spAbsAcc = -sprite->spAbsAcc;
|
|
sprite->sphasSlideFinished = 1;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
// not used
|
|
static bool8 BT_Phase2MugshotsSpriteFuncs_DecelerateSprite2(struct Sprite *sprite)
|
|
{
|
|
sprite->spSpeed += sprite->spAbsAcc;
|
|
sprite->pos1.x += sprite->spSpeed;
|
|
if (sprite->pos1.x < -31 || sprite->pos1.x > 271)
|
|
++sprite->spState;
|
|
return FALSE;
|
|
}
|
|
|
|
static void BT_SetSpriteAsOpponentOrPlayer(s16 spriteId, bool16 value)
|
|
{
|
|
gSprites[spriteId].spOpponentOrPlayer = value;
|
|
}
|
|
|
|
static void BT_StartSpriteSlide(s16 spriteId)
|
|
{
|
|
++gSprites[spriteId].spState;
|
|
}
|
|
|
|
static s16 BT_IsSpriteSlideFinished(s16 spriteId)
|
|
{
|
|
return gSprites[spriteId].sphasSlideFinished;
|
|
}
|
|
|
|
#undef tTheta
|
|
#undef tbg0HOfsOpponent
|
|
#undef tbg0HOfsPlayer
|
|
#undef tCounter
|
|
#undef tHalfBandwidth
|
|
#undef tOpponentSpriteId
|
|
#undef tPlayerSpriteId
|
|
#undef tWhichMugshot
|
|
|
|
#undef spState
|
|
#undef spSpeed
|
|
#undef spAbsAcc
|
|
#undef sphasSlideFinished
|
|
#undef spOpponentOrPlayer
|
|
|
|
#define tSpeed data[1]
|
|
#define tAcc data[2]
|
|
#define tJerk data[3]
|
|
|
|
static void BT_Phase2SlicedScreen(u8 taskId)
|
|
{
|
|
while (sBT_Phase2SlicedScreenFuncs[gTasks[taskId].tState](&gTasks[taskId]));
|
|
}
|
|
|
|
static bool8 BT_Phase2SlicedScreen_Init(struct Task *task)
|
|
{
|
|
u16 i;
|
|
|
|
BT_InitCtrlBlk();
|
|
ScanlineEffect_Clear();
|
|
task->tAcc = 256;
|
|
task->tJerk = 1;
|
|
sTransitionStructPtr->winIn = WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR;
|
|
sTransitionStructPtr->winOut = 0;
|
|
sTransitionStructPtr->win0V = WIN_RANGE(0, 0xA0);
|
|
for (i = 0; i < 160; ++i)
|
|
{
|
|
gScanlineEffectRegBuffers[1][i] = sTransitionStructPtr->bg123HOfs;
|
|
gScanlineEffectRegBuffers[1][160 + i] = 0xF0;
|
|
}
|
|
EnableInterrupts(INTR_FLAG_HBLANK);
|
|
SetVBlankCallback(VBCB_BT_Phase2SlicedScreen);
|
|
SetHBlankCallback(HBCB_BT_Phase2SlicedScreen);
|
|
++task->tState;
|
|
return TRUE;
|
|
}
|
|
|
|
static bool8 BT_Phase2SlicedScreen_UpdateOffsets(struct Task *task)
|
|
{
|
|
u16 i;
|
|
|
|
sTransitionStructPtr->vblankDma = FALSE;
|
|
task->tSpeed += (task->tAcc >> 8);
|
|
if (task->tSpeed > 0xF0)
|
|
task->tSpeed = 0xF0;
|
|
if (task->tAcc <= 0xFFF)
|
|
task->tAcc += task->tJerk;
|
|
if (task->tJerk < 128)
|
|
task->tJerk <<= 1;
|
|
for (i = 0; i < 160; ++i)
|
|
{
|
|
u16 *ofsBuffer = &gScanlineEffectRegBuffers[0][i];
|
|
u16 *win0HBuffer = &gScanlineEffectRegBuffers[0][i + 160];
|
|
if (i & 1)
|
|
{
|
|
*ofsBuffer = sTransitionStructPtr->bg123HOfs + task->tSpeed;
|
|
*win0HBuffer = 0xF0 - task->tSpeed;
|
|
}
|
|
else
|
|
{
|
|
*ofsBuffer = sTransitionStructPtr->bg123HOfs - task->tSpeed;
|
|
*win0HBuffer = WIN_RANGE(task->tSpeed, 0xF1);
|
|
}
|
|
}
|
|
if (task->tSpeed > 0xEF)
|
|
++task->tState;
|
|
++sTransitionStructPtr->vblankDma;
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 BT_Phase2SlicedScreen_End(struct Task *task)
|
|
{
|
|
DmaStop(0);
|
|
BT_BlendPalettesToBlack();
|
|
DestroyTask(FindTaskIdByFunc(BT_Phase2SlicedScreen));
|
|
return FALSE;
|
|
}
|
|
|
|
static void VBCB_BT_Phase2SlicedScreen(void)
|
|
{
|
|
DmaStop(0);
|
|
BT_VBSyncOamAndPltt();
|
|
SetGpuReg(REG_OFFSET_WININ, sTransitionStructPtr->winIn);
|
|
SetGpuReg(REG_OFFSET_WINOUT, sTransitionStructPtr->winOut);
|
|
SetGpuReg(REG_OFFSET_WIN0V, sTransitionStructPtr->win0V);
|
|
if (sTransitionStructPtr->vblankDma)
|
|
DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 640);
|
|
DmaSet(0, &gScanlineEffectRegBuffers[1][160], ®_WIN0H, ((DMA_ENABLE | DMA_START_HBLANK | DMA_REPEAT | DMA_16BIT | DMA_SRC_INC | DMA_DEST_FIXED) << 16) | 1);
|
|
}
|
|
|
|
static void HBCB_BT_Phase2SlicedScreen(void)
|
|
{
|
|
s16 offset = gScanlineEffectRegBuffers[1][REG_VCOUNT];
|
|
|
|
REG_BG1HOFS = offset;
|
|
REG_BG2HOFS = offset;
|
|
REG_BG3HOFS = offset;
|
|
}
|
|
|
|
#undef tSpeed
|
|
#undef tAcc
|
|
#undef tJerk
|
|
|
|
#define spBldyCounter data[0]
|
|
#define spFinished data[1]
|
|
#define spAltDelay data[2]
|
|
#define spDelay data[5]
|
|
#define spLastSprite data[6]
|
|
|
|
static void BT_Phase2WhiteFadeInStripes(u8 taskId)
|
|
{
|
|
while (sBT_Phase2WhiteFadeInStripesFuncs[gTasks[taskId].tState](&gTasks[taskId]));
|
|
}
|
|
|
|
static bool8 BT_Phase2WhiteFadeInStripes_Init(struct Task *task)
|
|
{
|
|
u16 i;
|
|
|
|
BT_InitCtrlBlk();
|
|
ScanlineEffect_Clear();
|
|
sTransitionStructPtr->bldCnt = BLDCNT_TGT1_BG0 | BLDCNT_TGT1_BG1 | BLDCNT_TGT1_BG2 | BLDCNT_TGT1_BG3 | BLDCNT_TGT1_OBJ | BLDCNT_TGT1_BD | BLDCNT_EFFECT_LIGHTEN;
|
|
sTransitionStructPtr->bldY = 0;
|
|
sTransitionStructPtr->winIn = WINOUT_WIN01_BG1 | WINOUT_WIN01_BG2 | WINOUT_WIN01_BG3 | WINOUT_WIN01_OBJ;
|
|
sTransitionStructPtr->winOut = WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WININ_WIN0_CLR;
|
|
sTransitionStructPtr->win0V = WIN_RANGE(0, 0xA0);
|
|
for (i = 0; i < 160; ++i)
|
|
{
|
|
gScanlineEffectRegBuffers[1][i] = 0;
|
|
gScanlineEffectRegBuffers[1][i + 160] = 0xF0;
|
|
}
|
|
EnableInterrupts(INTR_FLAG_HBLANK);
|
|
SetHBlankCallback(HBCB_BT_Phase2WhiteFadeInStripes);
|
|
SetVBlankCallback(VBCB_BT_Phase2WhiteFadeInStripes1);
|
|
++task->tState;
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 BT_Phase2WhiteFadeInStripes_SetupSprites(struct Task *task)
|
|
{
|
|
s16 i, posY;
|
|
s16 buffer[NELEMS(sWhiteStripeDelay)];
|
|
struct Sprite *sprite;
|
|
|
|
memcpy(buffer, sWhiteStripeDelay, sizeof(sWhiteStripeDelay));
|
|
for (i = 0, posY = 0; i < 6; ++i, posY += 0x1B)
|
|
{
|
|
sprite = &gSprites[CreateInvisibleSprite(SpriteCB_BT_Phase2WhiteFadeInStripes)];
|
|
sprite->pos1.x = 0xF0;
|
|
sprite->pos1.y = posY;
|
|
sprite->spDelay = buffer[i];
|
|
}
|
|
++sprite->spLastSprite;
|
|
++task->tState;
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 BT_Phase2WhiteFadeInStripes_IsWhiteFadeDone(struct Task *task)
|
|
{
|
|
sTransitionStructPtr->vblankDma = FALSE;
|
|
if (sTransitionStructPtr->counter > 5)
|
|
{
|
|
BlendPalettes(0xFFFFFFFF, 0x10, RGB_WHITE);
|
|
++task->tState;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 BT_Phase2WhiteFadeInStripes_Stop(struct Task *task)
|
|
{
|
|
sTransitionStructPtr->vblankDma = FALSE;
|
|
DmaStop(0);
|
|
SetVBlankCallback(NULL);
|
|
SetHBlankCallback(NULL);
|
|
sTransitionStructPtr->win0H = 240;
|
|
sTransitionStructPtr->bldY = 0;
|
|
sTransitionStructPtr->bldCnt = BLDCNT_TGT1_BG0 | BLDCNT_TGT1_BG1 | BLDCNT_TGT1_BG2 | BLDCNT_TGT1_BG3 | BLDCNT_TGT1_OBJ | BLDCNT_TGT1_BD | BLDCNT_EFFECT_DARKEN;
|
|
sTransitionStructPtr->winIn = WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WININ_WIN0_CLR;
|
|
sTransitionStructPtr->counter = 0;
|
|
SetVBlankCallback(VBCB_BT_Phase2WhiteFadeInStripes2);
|
|
++task->tState;
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 BT_Phase2WhiteFadeInStripes_IsDone(struct Task *task)
|
|
{
|
|
sTransitionStructPtr->counter += 480;
|
|
sTransitionStructPtr->bldY = sTransitionStructPtr->counter >> 8;
|
|
if (sTransitionStructPtr->bldY > 16)
|
|
{
|
|
BT_BlendPalettesToBlack();
|
|
DestroyTask(FindTaskIdByFunc(BT_Phase2WhiteFadeInStripes));
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static void VBCB_BT_Phase2WhiteFadeInStripes1(void)
|
|
{
|
|
DmaStop(0);
|
|
BT_VBSyncOamAndPltt();
|
|
SetGpuReg(REG_OFFSET_BLDCNT, sTransitionStructPtr->bldCnt);
|
|
SetGpuReg(REG_OFFSET_WININ, sTransitionStructPtr->winIn);
|
|
SetGpuReg(REG_OFFSET_WINOUT, sTransitionStructPtr->winOut);
|
|
SetGpuReg(REG_OFFSET_WIN0V, sTransitionStructPtr->win0H); // BUG: This should obviously be sTransitionStructPtr->win0V
|
|
if (sTransitionStructPtr->vblankDma)
|
|
DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 640);
|
|
DmaSet(0, &gScanlineEffectRegBuffers[1][160], ®_WIN0H, ((DMA_ENABLE | DMA_START_HBLANK | DMA_REPEAT | DMA_16BIT | DMA_SRC_INC | DMA_DEST_FIXED) << 16) | 1);
|
|
}
|
|
|
|
static void VBCB_BT_Phase2WhiteFadeInStripes2(void)
|
|
{
|
|
BT_VBSyncOamAndPltt();
|
|
SetGpuReg(REG_OFFSET_BLDY, sTransitionStructPtr->bldY);
|
|
SetGpuReg(REG_OFFSET_BLDCNT, sTransitionStructPtr->bldCnt);
|
|
SetGpuReg(REG_OFFSET_WININ, sTransitionStructPtr->winIn);
|
|
SetGpuReg(REG_OFFSET_WINOUT, sTransitionStructPtr->winOut);
|
|
SetGpuReg(REG_OFFSET_WIN0H, sTransitionStructPtr->win0H);
|
|
SetGpuReg(REG_OFFSET_WIN0V, sTransitionStructPtr->win0V);
|
|
}
|
|
|
|
|
|
static void HBCB_BT_Phase2WhiteFadeInStripes(void)
|
|
{
|
|
vu16 index = REG_VCOUNT;
|
|
|
|
if (index == 227)
|
|
index = 0;
|
|
REG_BLDY = gScanlineEffectRegBuffers[1][index];
|
|
}
|
|
|
|
static void SpriteCB_BT_Phase2WhiteFadeInStripes(struct Sprite *sprite)
|
|
{
|
|
if (sprite->spDelay)
|
|
{
|
|
--sprite->spDelay;
|
|
if (sprite->spLastSprite)
|
|
sTransitionStructPtr->vblankDma = TRUE;
|
|
}
|
|
else
|
|
{
|
|
u16 i;
|
|
u16 *bldY = &gScanlineEffectRegBuffers[0][sprite->pos1.y];
|
|
u16 *win0H = &gScanlineEffectRegBuffers[0][sprite->pos1.y + 160];
|
|
u32 stripeWidth = sprite->spLastSprite ? 0x19 : 0x1B;
|
|
|
|
for (i = 0; i < stripeWidth; ++i)
|
|
{
|
|
bldY[i] = sprite->spBldyCounter >> 8;
|
|
win0H[i] = (u8)(sprite->pos1.x);
|
|
}
|
|
if (sprite->pos1.x == 0 && sprite->spBldyCounter == 0x1000)
|
|
sprite->spFinished = 1;
|
|
sprite->pos1.x -= 24;
|
|
sprite->spBldyCounter += 192;
|
|
if (sprite->pos1.x < 0)
|
|
sprite->pos1.x = 0;
|
|
if (sprite->spBldyCounter > 0x1000)
|
|
sprite->spBldyCounter = 0x1000;
|
|
if (sprite->spLastSprite)
|
|
sTransitionStructPtr->vblankDma = TRUE;
|
|
if (sprite->spFinished)
|
|
{
|
|
if (sprite->spLastSprite == FALSE || (sTransitionStructPtr->counter > 4))
|
|
{
|
|
++sTransitionStructPtr->counter;
|
|
DestroySprite(sprite);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#undef spBldyCounter
|
|
#undef spFinished
|
|
#undef spAltDelay
|
|
#undef spDelay
|
|
#undef spLastSprite
|
|
|
|
#define tDelay data[1]
|
|
#define tWhichGrid data[2]
|
|
|
|
static void BT_Phase2GridSquares(u8 taskId)
|
|
{
|
|
while (sBT_Phase2GridSquaresFuncs[gTasks[taskId].tState](&gTasks[taskId]));
|
|
}
|
|
|
|
static bool8 BT_Phase2GridSquares_LoadGfx(struct Task *task)
|
|
{
|
|
u16 *tilemapAddr, *tilesetAddr;
|
|
|
|
BT_GetBg0TilemapAndTilesetBase(&tilemapAddr, &tilesetAddr);
|
|
CpuSet(sGridSquareTileset, tilesetAddr, 0x10);
|
|
CpuFill16(0xF000, tilemapAddr, 0x800);
|
|
LoadPalette(sSlidingPokeballBigPokeballPalette, 0xF0, 0x20);
|
|
++task->tState;
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 BT_Phase2GridSquares_UpdateTileset(struct Task *task)
|
|
{
|
|
u16 *tilesetAddr;
|
|
|
|
if (task->tDelay == 0)
|
|
{
|
|
BT_GetBg0TilesetBase(&tilesetAddr);
|
|
task->tDelay = 3;
|
|
++task->tWhichGrid;
|
|
CpuSet(sGridSquareTileset + (task->tWhichGrid * 8), tilesetAddr, 0x10);
|
|
if (task->tWhichGrid > 0xD)
|
|
{
|
|
++task->tState;
|
|
task->tDelay = 16;
|
|
}
|
|
}
|
|
--task->tDelay;
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 BT_Phase2GridSquares_IsDone(struct Task *task)
|
|
{
|
|
if (--task->tDelay == 0)
|
|
{
|
|
BT_BlendPalettesToBlack();
|
|
DestroyTask(FindTaskIdByFunc(BT_Phase2GridSquares));
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
#undef tDelay
|
|
#undef tWhichGrid
|
|
|
|
#define tWhichBrush data[1]
|
|
#define tWhichSide data[2]
|
|
#define tDelay data[3]
|
|
|
|
#define trCurrentPtX data[2]
|
|
#define trCurrentPtY data[3]
|
|
|
|
static void BT_Phase2BlackDoodles(u8 taskId)
|
|
{
|
|
while (sBT_Phase2BlackDoodlesFuncs[gTasks[taskId].tState](&gTasks[taskId]));
|
|
}
|
|
|
|
static bool8 BT_Phase2BlackDoodles_Init(struct Task *task)
|
|
{
|
|
u16 i;
|
|
|
|
BT_InitCtrlBlk();
|
|
ScanlineEffect_Clear();
|
|
sTransitionStructPtr->winIn = WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR;
|
|
sTransitionStructPtr->winOut = 0;
|
|
sTransitionStructPtr->win0V = WIN_RANGE(0, 0xA0);
|
|
for (i = 0; i < 160; ++i)
|
|
gScanlineEffectRegBuffers[0][i] = WIN_RANGE(0, 0xF0);
|
|
CpuSet(gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 160);
|
|
SetVBlankCallback(VBCB_BT_Phase2BlackDoodles);
|
|
++task->tState;
|
|
return TRUE;
|
|
}
|
|
|
|
static bool8 BT_Phase2BlackDoodles_InitSingleBrush(struct Task *task)
|
|
{
|
|
BT_DiagonalSegment_InitParams(sTransitionStructPtr->data, sBlackDoodlesSegments[task->tWhichBrush][0], sBlackDoodlesSegments[task->tWhichBrush][1], sBlackDoodlesSegments[task->tWhichBrush][2], sBlackDoodlesSegments[task->tWhichBrush][3], 1, 1);
|
|
task->tWhichSide = sBlackDoodlesSegments[task->tWhichBrush][4];
|
|
++task->tState;
|
|
return TRUE;
|
|
}
|
|
|
|
static bool8 BT_Phase2BlackDoodles_DrawSingleBrush(struct Task *task)
|
|
{
|
|
s16 i;
|
|
bool8 nextFunc;
|
|
|
|
sTransitionStructPtr->vblankDma = FALSE;
|
|
for (i = 0, nextFunc = FALSE; i < 16; ++i)
|
|
{
|
|
s16 left = gScanlineEffectRegBuffers[0][sTransitionStructPtr->trCurrentPtY] >> 8;
|
|
s16 right = gScanlineEffectRegBuffers[0][sTransitionStructPtr->trCurrentPtY] & 0xFF;
|
|
if (task->tWhichSide == 0)
|
|
{
|
|
if (left < sTransitionStructPtr->trCurrentPtX)
|
|
left = sTransitionStructPtr->trCurrentPtX;
|
|
if (left > right)
|
|
left = right;
|
|
}
|
|
else
|
|
{
|
|
if (right > sTransitionStructPtr->trCurrentPtX)
|
|
right = sTransitionStructPtr->trCurrentPtX;
|
|
if (right <= left)
|
|
right = left;
|
|
}
|
|
gScanlineEffectRegBuffers[0][sTransitionStructPtr->trCurrentPtY] = WIN_RANGE2(left, right);
|
|
if (nextFunc)
|
|
{
|
|
++task->tState;
|
|
break;
|
|
}
|
|
else
|
|
nextFunc = BT_DiagonalSegment_ComputePointOnSegment(sTransitionStructPtr->data, TRUE, TRUE);
|
|
}
|
|
++sTransitionStructPtr->vblankDma;
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 BT_Phase2BlackDoodles_IsDone(struct Task *task)
|
|
{
|
|
if (++task->tWhichBrush < 7)
|
|
{
|
|
++task->tState;
|
|
task->tDelay = sBlackDoodlesDelay[task->tWhichBrush - 1];
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
DmaStop(0);
|
|
BT_BlendPalettesToBlack();
|
|
DestroyTask(FindTaskIdByFunc(BT_Phase2BlackDoodles));
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
static bool8 BT_Phase2BlackDoodles_NextBrush(struct Task *task)
|
|
{
|
|
if (--task->tDelay == 0)
|
|
{
|
|
task->tState = 1;
|
|
return TRUE;
|
|
}
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
static void VBCB_BT_Phase2BlackDoodles(void)
|
|
{
|
|
DmaStop(0);
|
|
BT_VBSyncOamAndPltt();
|
|
if (sTransitionStructPtr->vblankDma)
|
|
DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320);
|
|
SetGpuReg(REG_OFFSET_WININ, sTransitionStructPtr->winIn);
|
|
SetGpuReg(REG_OFFSET_WINOUT, sTransitionStructPtr->winOut);
|
|
SetGpuReg(REG_OFFSET_WIN0V, sTransitionStructPtr->win0V);
|
|
SetGpuReg(REG_OFFSET_WIN0H, gScanlineEffectRegBuffers[1][0]);
|
|
DmaSet(0, gScanlineEffectRegBuffers[1], ®_WIN0H, ((DMA_ENABLE | DMA_START_HBLANK | DMA_REPEAT | DMA_16BIT | DMA_SRC_INC | DMA_DEST_FIXED) << 16) | 1);
|
|
}
|
|
|
|
#undef tWhichBrush
|
|
#undef tWhichSide
|
|
#undef tDelay
|
|
|
|
#undef trCurrentPtX
|
|
#undef trCurrentPtY
|
|
|
|
#define tFadeOutDelay data[1]
|
|
#define tFadeInDelay data[2]
|
|
#define tBlinkTimes data[3]
|
|
#define tFadeOutSpeed data[4]
|
|
#define tFadeInSpeed data[5]
|
|
#define tDelayCounter data[6]
|
|
#define tCoeff data[7]
|
|
|
|
static void BT_CreatePhase1SubTask(s16 fadeOutDelay, s16 fadeInDelay, s16 blinkTimes, s16 fadeOutSpeed, s16 fadeInSpeed)
|
|
{
|
|
u8 taskId = CreateTask(BT_Phase1SubTask, 3);
|
|
gTasks[taskId].tFadeOutDelay = fadeOutDelay;
|
|
gTasks[taskId].tFadeInDelay = fadeInDelay;
|
|
gTasks[taskId].tBlinkTimes = blinkTimes;
|
|
gTasks[taskId].tFadeOutSpeed = fadeOutSpeed;
|
|
gTasks[taskId].tFadeInSpeed = fadeInSpeed;
|
|
gTasks[taskId].tDelayCounter = fadeOutDelay;
|
|
}
|
|
|
|
static bool8 BT_IsPhase1Done(void)
|
|
{
|
|
if (FindTaskIdByFunc(BT_Phase1SubTask) == TASK_NONE)
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
static void BT_Phase1SubTask(u8 taskId)
|
|
{
|
|
while (sBT_Phase1FadeFuncs[gTasks[taskId].tState](&gTasks[taskId]));
|
|
}
|
|
|
|
static bool8 BT_Phase1_FadeOut(struct Task *task)
|
|
{
|
|
if (task->tDelayCounter == 0 || --task->tDelayCounter == 0)
|
|
{
|
|
task->tDelayCounter = task->tFadeOutDelay;
|
|
task->tCoeff += task->tFadeOutSpeed;
|
|
if (task->tCoeff > 16)
|
|
task->tCoeff = 16;
|
|
BlendPalettes(-1, task->tCoeff, RGB(11, 11, 11));
|
|
}
|
|
if (task->tCoeff > 15)
|
|
{
|
|
++task->tState;
|
|
task->tDelayCounter = task->tFadeInDelay;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 BT_Phase1_FadeIn(struct Task *task)
|
|
{
|
|
if (task->tDelayCounter == 0 || --task->tDelayCounter == 0)
|
|
{
|
|
task->tDelayCounter = task->tFadeInDelay;
|
|
task->tCoeff -= task->tFadeInSpeed;
|
|
if (task->tCoeff < 0)
|
|
task->tCoeff = 0;
|
|
BlendPalettes(0xFFFFFFFF, task->tCoeff, RGB(11, 11, 11));
|
|
}
|
|
if (task->tCoeff == 0)
|
|
{
|
|
if (--task->tBlinkTimes == 0)
|
|
{
|
|
DestroyTask(FindTaskIdByFunc(BT_Phase1SubTask));
|
|
}
|
|
else
|
|
{
|
|
task->tDelayCounter = task->tFadeOutDelay;
|
|
task->tState = 0;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
#undef tFadeOutDelay
|
|
#undef tFadeInDelay
|
|
#undef tBlinkTimes
|
|
#undef tFadeOutSpeed
|
|
#undef tFadeInSpeed
|
|
#undef tDelayCounter
|
|
#undef tCoeff
|
|
|
|
static void BT_InitCtrlBlk(void)
|
|
{
|
|
memset(sTransitionStructPtr, 0, sizeof(*sTransitionStructPtr));
|
|
sub_805A658(&sTransitionStructPtr->bg123HOfs, &sTransitionStructPtr->bg123VOfs);
|
|
}
|
|
|
|
static void BT_VBSyncOamAndPltt(void)
|
|
{
|
|
LoadOam();
|
|
ProcessSpriteCopyRequests();
|
|
TransferPlttBuffer();
|
|
}
|
|
|
|
static void BT_GetBg0TilesetBase(u16 **tilesetPtr)
|
|
{
|
|
u16 charBase;
|
|
|
|
charBase = GetGpuReg(REG_OFFSET_BG0CNT) >> 2;
|
|
charBase <<= 0xE;
|
|
*tilesetPtr = (u16 *)(VRAM + charBase);
|
|
}
|
|
|
|
static void BT_GetBg0TilemapAndTilesetBase(u16 **tilemapPtr, u16 **tilesetPtr)
|
|
{
|
|
u16 screenBase, charBase;
|
|
|
|
screenBase = (GetGpuReg(REG_OFFSET_BG0CNT) >> 8) & 0x1F;
|
|
charBase = GetGpuReg(REG_OFFSET_BG0CNT) >> 2;
|
|
screenBase <<= 0xB;
|
|
charBase <<= 0xE;
|
|
*tilemapPtr = (u16 *)(VRAM + screenBase);
|
|
*tilesetPtr = (u16 *)(VRAM + charBase);
|
|
}
|
|
|
|
static void BT_BlendPalettesToBlack(void)
|
|
{
|
|
BlendPalettes(0xFFFFFFFF, 0x10, RGB_BLACK);
|
|
}
|
|
|
|
static void BT_LoadWaveIntoBuffer(s16 *buffer, s16 offset, s16 theta, s16 frequency, s16 amplitude, s16 bufSize)
|
|
{
|
|
u8 i;
|
|
|
|
for (i = 0; bufSize > 0; --bufSize, ++i, theta += frequency)
|
|
buffer[i] = offset + Sin(0xFF & theta, amplitude);
|
|
}
|
|
|
|
static void BT_GenerateCircle(s16 *buffer, s16 x, s16 y, s16 radius)
|
|
{
|
|
s16 i;
|
|
|
|
memset(buffer, 0xA, 320);
|
|
// 64 iterations because we only want to cover [0, π/2) discretely.
|
|
for (i = 0; i < 64; ++i)
|
|
{
|
|
s16 sinResult, cosResult, leftX, topY, bottomY, nextTopY, nextBottomY, winVal;
|
|
|
|
// The loop variable i here does not stand for rotation angle,
|
|
// but is the angle between segment (center, pointOnCircle)
|
|
// and vertical line.
|
|
sinResult = Sin(i, radius);
|
|
cosResult = Cos(i, radius);
|
|
leftX = x - sinResult;
|
|
winVal = x + sinResult;
|
|
topY = y - cosResult;
|
|
bottomY = y + cosResult;
|
|
if (leftX < 0)
|
|
leftX = 0;
|
|
if (winVal > 240)
|
|
winVal = 240;
|
|
if (topY < 0)
|
|
topY = 0;
|
|
if (bottomY > 159)
|
|
bottomY = 159;
|
|
winVal |= (leftX << 8);
|
|
buffer[topY] = winVal;
|
|
buffer[bottomY] = winVal;
|
|
cosResult = Cos(i + 1, radius);
|
|
nextTopY = y - cosResult;
|
|
nextBottomY = y + cosResult;
|
|
if (nextTopY < 0)
|
|
nextTopY = 0;
|
|
if (nextBottomY > 159)
|
|
nextBottomY = 159;
|
|
// fill everything in between with the same WIN0H value
|
|
while (topY > nextTopY)
|
|
buffer[--topY] = winVal;
|
|
while (topY < nextTopY)
|
|
buffer[++topY] = winVal;
|
|
while (bottomY > nextBottomY)
|
|
buffer[--bottomY] = winVal;
|
|
while (bottomY < nextBottomY)
|
|
buffer[++bottomY] = winVal;
|
|
}
|
|
}
|
|
|
|
#define trStartPtX data[0]
|
|
#define trStartPtY data[1]
|
|
#define trCurrentPtX data[2]
|
|
#define trCurrentPtY data[3]
|
|
#define trEndPtX data[4]
|
|
#define trEndPtY data[5]
|
|
#define trStepX data[6]
|
|
#define trStepY data[7]
|
|
#define trAbsDeltaX data[8]
|
|
#define trAbsDeltaY data[9]
|
|
#define trAccum data[10] // track one dimension based on slope
|
|
|
|
static void BT_DiagonalSegment_InitParams(s16 *data, s16 startPtX, s16 startPtY, s16 endPtX, s16 endPtY, s16 stepX, s16 stepY)
|
|
{
|
|
trStartPtX = startPtX;
|
|
trStartPtY = startPtY;
|
|
trCurrentPtX = startPtX;
|
|
trCurrentPtY = startPtY;
|
|
trEndPtX = endPtX;
|
|
trEndPtY = endPtY;
|
|
trStepX = stepX;
|
|
trStepY = stepY;
|
|
trAbsDeltaX = endPtX - startPtX;
|
|
if (trAbsDeltaX < 0)
|
|
{
|
|
trAbsDeltaX = -trAbsDeltaX;
|
|
trStepX = -stepX;
|
|
}
|
|
trAbsDeltaY = endPtY - startPtY;
|
|
if (trAbsDeltaY < 0)
|
|
{
|
|
trAbsDeltaY = -trAbsDeltaY;
|
|
trStepY = -stepY;
|
|
}
|
|
trAccum = 0;
|
|
}
|
|
|
|
static bool8 BT_DiagonalSegment_ComputePointOnSegment(s16 *data, bool8 checkBoundary1, bool8 checkBoundary2)
|
|
{
|
|
u8 finish;
|
|
|
|
if (trAbsDeltaX > trAbsDeltaY)
|
|
{
|
|
trCurrentPtX += trStepX;
|
|
trAccum += trAbsDeltaY;
|
|
if (trAccum > trAbsDeltaX)
|
|
{
|
|
trCurrentPtY += trStepY;
|
|
trAccum -= trAbsDeltaX;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
trCurrentPtY += trStepY;
|
|
trAccum += trAbsDeltaX;
|
|
if (trAccum > trAbsDeltaY)
|
|
{
|
|
trCurrentPtX += trStepX;
|
|
trAccum -= trAbsDeltaY;
|
|
}
|
|
}
|
|
finish = 0;
|
|
if ((trStepX > 0 && trCurrentPtX >= trEndPtX) || (trStepX < 0 && trCurrentPtX <= trEndPtX))
|
|
{
|
|
++finish;
|
|
if (checkBoundary1)
|
|
trCurrentPtX = trEndPtX;
|
|
}
|
|
if ((trStepY > 0 && trCurrentPtY >= trEndPtY) || (trStepY < 0 && trCurrentPtY <= trEndPtY))
|
|
{
|
|
++finish;
|
|
if (checkBoundary2)
|
|
trCurrentPtY = trEndPtY;
|
|
}
|
|
if (finish == 2)
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
#undef trStartPtX
|
|
#undef trStartPtY
|
|
#undef trCurrentPtX
|
|
#undef trCurrentPtY
|
|
#undef trEndPtX
|
|
#undef trEndPtY
|
|
#undef trStepX
|
|
#undef trStepY
|
|
#undef trAbsDeltaX
|
|
#undef trAbsDeltaY
|
|
#undef trAccum
|