pokeemerald/src/field_screen_effect.c

1276 lines
30 KiB
C
Raw Normal View History

2018-12-08 21:42:36 +01:00
#include "global.h"
#include "cable_club.h"
#include "event_data.h"
#include "fieldmap.h"
#include "field_camera.h"
#include "field_door.h"
#include "field_effect.h"
#include "event_object_lock.h"
2018-12-08 21:42:36 +01:00
#include "event_object_movement.h"
#include "field_player_avatar.h"
2018-12-08 22:05:11 +01:00
#include "field_screen_effect.h"
2018-12-08 21:42:36 +01:00
#include "field_special_scene.h"
#include "field_weather.h"
#include "gpu_regs.h"
#include "io_reg.h"
2018-12-08 21:42:36 +01:00
#include "link.h"
#include "link_rfu.h"
#include "load_save.h"
#include "main.h"
#include "menu.h"
#include "mirage_tower.h"
2018-12-08 21:42:36 +01:00
#include "metatile_behavior.h"
#include "palette.h"
#include "overworld.h"
#include "scanline_effect.h"
#include "script.h"
#include "sound.h"
#include "start_menu.h"
#include "task.h"
#include "text.h"
2019-11-21 20:03:35 +01:00
#include "constants/event_object_movement.h"
2019-12-17 09:24:44 +01:00
#include "constants/event_objects.h"
2018-12-08 21:42:36 +01:00
#include "constants/songs.h"
#include "constants/rgb.h"
2019-03-02 04:32:50 +01:00
#include "trainer_hill.h"
2019-03-02 08:44:02 +01:00
#include "fldeff.h"
2018-12-08 21:42:36 +01:00
2018-12-08 22:05:11 +01:00
// This file's functions.
2019-12-17 09:24:44 +01:00
static void Task_ExitNonAnimDoor(u8);
static void Task_ExitNonDoor(u8);
static void Task_DoContestHallWarp(u8);
2019-12-17 09:24:44 +01:00
static void FillPalBufferWhite(void);
static void Task_ExitDoor(u8);
static bool32 WaitForWeatherFadeIn(void);
2021-01-01 21:34:21 +01:00
static void Task_SpinEnterWarp(u8 taskId);
2019-12-17 09:24:44 +01:00
static void Task_WarpAndLoadMap(u8 taskId);
static void Task_DoDoorWarp(u8 taskId);
2019-10-07 02:04:30 +02:00
static void Task_EnableScriptAfterMusicFade(u8 taskId);
2018-12-08 22:05:11 +01:00
2021-01-01 21:34:21 +01:00
// data[0] is used universally by tasks in this file as a state for switches
#define tState data[0]
2018-12-08 22:05:11 +01:00
// const
2019-12-17 09:24:44 +01:00
static const u16 sFlashLevelPixelRadii[] = { 200, 72, 64, 56, 48, 40, 32, 24, 0 };
const s32 gMaxFlashLevel = ARRAY_COUNT(sFlashLevelPixelRadii) - 1;
2018-12-08 21:42:36 +01:00
const struct ScanlineEffectParams sFlashEffectParams =
{
(void *)REG_ADDR_WIN0H,
((DMA_ENABLE | DMA_START_HBLANK | DMA_REPEAT | DMA_DEST_RELOAD) << 16) | 1,
1
};
2018-12-08 22:05:11 +01:00
// code
2019-12-17 09:24:44 +01:00
static void FillPalBufferWhite(void)
2018-12-08 21:42:36 +01:00
{
CpuFastFill16(RGB_WHITE, gPlttBufferFaded, PLTT_SIZE);
}
2019-12-17 09:24:44 +01:00
static void FillPalBufferBlack(void)
2018-12-08 21:42:36 +01:00
{
CpuFastFill16(RGB_BLACK, gPlttBufferFaded, PLTT_SIZE);
}
2019-12-17 09:24:44 +01:00
void WarpFadeInScreen(void)
2018-12-08 21:42:36 +01:00
{
u8 previousMapType = GetLastUsedWarpMapType();
2018-12-27 23:30:47 +01:00
switch (GetMapPairFadeFromType(previousMapType, GetCurrentMapType()))
2018-12-08 21:42:36 +01:00
{
case 0:
2019-12-17 09:24:44 +01:00
FillPalBufferBlack();
2018-12-08 21:42:36 +01:00
FadeScreen(FADE_FROM_BLACK, 0);
break;
case 1:
2019-12-17 09:24:44 +01:00
FillPalBufferWhite();
2018-12-08 21:42:36 +01:00
FadeScreen(FADE_FROM_WHITE, 0);
}
}
2019-12-17 09:24:44 +01:00
void FadeInFromWhite(void)
2018-12-08 21:42:36 +01:00
{
2019-12-17 09:24:44 +01:00
FillPalBufferWhite();
2018-12-08 21:42:36 +01:00
FadeScreen(FADE_FROM_WHITE, 8);
}
2019-12-17 09:24:44 +01:00
void FadeInFromBlack(void)
2018-12-08 21:42:36 +01:00
{
2019-12-17 09:24:44 +01:00
FillPalBufferBlack();
2018-12-08 21:42:36 +01:00
FadeScreen(FADE_FROM_BLACK, 0);
}
2019-12-17 09:24:44 +01:00
void WarpFadeOutScreen(void)
2018-12-08 21:42:36 +01:00
{
2018-12-27 23:30:47 +01:00
u8 currentMapType = GetCurrentMapType();
2018-12-08 21:42:36 +01:00
switch (GetMapPairFadeToType(currentMapType, GetDestinationWarpMapHeader()->mapType))
{
case 0:
FadeScreen(FADE_TO_BLACK, 0);
break;
case 1:
FadeScreen(FADE_TO_WHITE, 0);
}
}
2019-12-17 09:24:44 +01:00
static void SetPlayerVisibility(bool8 visible)
2018-12-08 21:42:36 +01:00
{
2019-12-17 09:24:44 +01:00
SetPlayerInvisibility(!visible);
2018-12-08 21:42:36 +01:00
}
2019-12-17 09:24:44 +01:00
static void Task_WaitForUnionRoomFade(u8 taskId)
2018-12-08 21:42:36 +01:00
{
if (WaitForWeatherFadeIn() == TRUE)
2018-12-08 21:42:36 +01:00
DestroyTask(taskId);
}
2019-12-17 09:24:44 +01:00
void FieldCB_ContinueScriptUnionRoom(void)
2018-12-08 21:42:36 +01:00
{
ScriptContext2_Enable();
Overworld_PlaySpecialMapMusic();
2019-12-17 09:24:44 +01:00
FadeInFromBlack();
CreateTask(Task_WaitForUnionRoomFade, 10);
2018-12-08 21:42:36 +01:00
}
2019-12-17 09:24:44 +01:00
static void Task_WaitForFadeAndEnableScriptCtx(u8 taskID)
2018-12-08 21:42:36 +01:00
{
if (WaitForWeatherFadeIn() == TRUE)
2018-12-08 21:42:36 +01:00
{
DestroyTask(taskID);
EnableBothScriptContexts();
}
}
2019-12-17 09:24:44 +01:00
void FieldCB_ContinueScriptHandleMusic(void)
2018-12-08 21:42:36 +01:00
{
ScriptContext2_Enable();
Overworld_PlaySpecialMapMusic();
2019-12-17 09:24:44 +01:00
FadeInFromBlack();
CreateTask(Task_WaitForFadeAndEnableScriptCtx, 10);
2018-12-08 21:42:36 +01:00
}
2019-12-17 09:24:44 +01:00
void FieldCB_ContinueScript(void)
2018-12-08 21:42:36 +01:00
{
ScriptContext2_Enable();
2019-12-17 09:24:44 +01:00
FadeInFromBlack();
CreateTask(Task_WaitForFadeAndEnableScriptCtx, 10);
2018-12-08 21:42:36 +01:00
}
2019-12-17 09:24:44 +01:00
static void Task_ReturnToFieldCableLink(u8 taskId)
2018-12-08 21:42:36 +01:00
{
struct Task *task = &gTasks[taskId];
2021-01-01 21:34:21 +01:00
switch (task->tState)
2018-12-08 21:42:36 +01:00
{
case 0:
2020-06-04 00:00:53 +02:00
task->data[1] = CreateTask_ReestablishCableClubLink();
2021-01-01 21:34:21 +01:00
task->tState++;
2018-12-08 21:42:36 +01:00
break;
case 1:
if (gTasks[task->data[1]].isActive != TRUE)
{
2019-12-17 09:24:44 +01:00
WarpFadeInScreen();
2021-01-01 21:34:21 +01:00
task->tState++;
2018-12-08 21:42:36 +01:00
}
break;
case 2:
if (WaitForWeatherFadeIn() == TRUE)
2018-12-08 21:42:36 +01:00
{
ScriptContext2_Disable();
DestroyTask(taskId);
}
break;
}
}
2019-12-17 09:24:44 +01:00
void FieldCB_ReturnToFieldCableLink(void)
2018-12-08 21:42:36 +01:00
{
ScriptContext2_Enable();
Overworld_PlaySpecialMapMusic();
2019-12-17 09:24:44 +01:00
FillPalBufferBlack();
CreateTask(Task_ReturnToFieldCableLink, 10);
2018-12-08 21:42:36 +01:00
}
2019-12-17 09:24:44 +01:00
static void Task_ReturnToFieldWirelessLink(u8 taskId)
2018-12-08 21:42:36 +01:00
{
struct Task *task = &gTasks[taskId];
2021-01-01 21:34:21 +01:00
switch (task->tState)
2018-12-08 21:42:36 +01:00
{
case 0:
2020-08-13 09:09:47 +02:00
SetLinkStandbyCallback();
2021-01-01 21:34:21 +01:00
task->tState++;
2018-12-08 21:42:36 +01:00
break;
case 1:
2018-12-31 09:22:21 +01:00
if (!IsLinkTaskFinished())
2018-12-08 21:42:36 +01:00
{
if (++task->data[1] > 1800)
2020-06-06 22:46:19 +02:00
GetLinkmanErrorParams(0x6000);
2018-12-08 21:42:36 +01:00
}
else
{
2019-12-17 09:24:44 +01:00
WarpFadeInScreen();
2021-01-01 21:34:21 +01:00
task->tState++;
2018-12-08 21:42:36 +01:00
}
break;
case 2:
if (WaitForWeatherFadeIn() == TRUE)
2018-12-08 21:42:36 +01:00
{
StartSendingKeysToLink();
2018-12-08 21:42:36 +01:00
ScriptContext2_Disable();
DestroyTask(taskId);
}
break;
}
}
2019-12-17 09:24:44 +01:00
void Task_ReturnToFieldRecordMixing(u8 taskId)
2018-12-08 21:42:36 +01:00
{
struct Task *task = &gTasks[taskId];
2021-01-01 21:34:21 +01:00
switch (task->tState)
2018-12-08 21:42:36 +01:00
{
case 0:
2020-08-13 09:09:47 +02:00
SetLinkStandbyCallback();
2021-01-01 21:34:21 +01:00
task->tState++;
2018-12-08 21:42:36 +01:00
break;
case 1:
2018-12-31 09:22:21 +01:00
if (IsLinkTaskFinished())
2018-12-08 21:42:36 +01:00
{
2021-01-01 21:34:21 +01:00
task->tState++;
2018-12-08 21:42:36 +01:00
}
break;
case 2:
StartSendingKeysToLink();
ResetAllMultiplayerState();
2018-12-08 21:42:36 +01:00
ScriptContext2_Disable();
DestroyTask(taskId);
break;
}
}
2019-12-17 09:24:44 +01:00
void FieldCB_ReturnToFieldWirelessLink(void)
2018-12-08 21:42:36 +01:00
{
ScriptContext2_Enable();
Overworld_PlaySpecialMapMusic();
2019-12-17 09:24:44 +01:00
FillPalBufferBlack();
CreateTask(Task_ReturnToFieldWirelessLink, 10);
2018-12-08 21:42:36 +01:00
}
2019-12-17 09:24:44 +01:00
static void SetUpWarpExitTask(void)
2018-12-08 21:42:36 +01:00
{
s16 x, y;
u8 behavior;
TaskFunc func;
PlayerGetDestCoords(&x, &y);
behavior = MapGridGetMetatileBehaviorAt(x, y);
if (MetatileBehavior_IsDoor(behavior) == TRUE)
2019-12-17 09:24:44 +01:00
func = Task_ExitDoor;
2018-12-08 21:42:36 +01:00
else if (MetatileBehavior_IsNonAnimDoor(behavior) == TRUE)
2019-12-17 09:24:44 +01:00
func = Task_ExitNonAnimDoor;
2018-12-08 21:42:36 +01:00
else
2019-12-17 09:24:44 +01:00
func = Task_ExitNonDoor;
2018-12-08 21:42:36 +01:00
CreateTask(func, 10);
}
2019-12-17 09:24:44 +01:00
void FieldCB_DefaultWarpExit(void)
2018-12-08 21:42:36 +01:00
{
Overworld_PlaySpecialMapMusic();
2019-12-17 09:24:44 +01:00
WarpFadeInScreen();
SetUpWarpExitTask();
2018-12-08 21:42:36 +01:00
ScriptContext2_Enable();
}
2019-12-17 09:24:44 +01:00
void FieldCB_WarpExitFadeFromWhite(void)
2018-12-08 21:42:36 +01:00
{
Overworld_PlaySpecialMapMusic();
2019-12-17 09:24:44 +01:00
FadeInFromWhite();
SetUpWarpExitTask();
2018-12-08 21:42:36 +01:00
ScriptContext2_Enable();
}
2019-12-17 09:24:44 +01:00
void FieldCB_WarpExitFadeFromBlack(void)
2018-12-08 21:42:36 +01:00
{
if (!OnTrainerHillEReaderChallengeFloor()) // always false
2018-12-08 21:42:36 +01:00
Overworld_PlaySpecialMapMusic();
2019-12-17 09:24:44 +01:00
FadeInFromBlack();
SetUpWarpExitTask();
2018-12-08 21:42:36 +01:00
ScriptContext2_Enable();
}
2021-01-01 21:34:21 +01:00
static void FieldCB_SpinEnterWarp(void)
2018-12-08 21:42:36 +01:00
{
Overworld_PlaySpecialMapMusic();
2019-12-17 09:24:44 +01:00
WarpFadeInScreen();
2020-08-21 00:02:00 +02:00
PlaySE(SE_WARP_OUT);
2021-01-01 21:34:21 +01:00
CreateTask(Task_SpinEnterWarp, 10);
2018-12-08 21:42:36 +01:00
ScriptContext2_Enable();
}
2019-12-17 09:24:44 +01:00
static void FieldCB_MossdeepGymWarpExit(void)
2018-12-08 21:42:36 +01:00
{
Overworld_PlaySpecialMapMusic();
2019-12-17 09:24:44 +01:00
WarpFadeInScreen();
2020-08-21 00:02:00 +02:00
PlaySE(SE_WARP_OUT);
2019-12-17 09:24:44 +01:00
CreateTask(Task_ExitNonDoor, 10);
2018-12-08 21:42:36 +01:00
ScriptContext2_Enable();
SetObjectEventLoadFlag((~SKIP_OBJECT_EVENT_LOAD) & 0xF);
2018-12-08 21:42:36 +01:00
}
2019-12-17 09:24:44 +01:00
static void Task_ExitDoor(u8 taskId)
2018-12-08 21:42:36 +01:00
{
struct Task *task = &gTasks[taskId];
s16 *x = &task->data[2];
s16 *y = &task->data[3];
2021-01-01 21:34:21 +01:00
switch (task->tState)
2018-12-08 21:42:36 +01:00
{
case 0:
2019-12-17 09:24:44 +01:00
SetPlayerVisibility(FALSE);
FreezeObjectEvents();
2018-12-08 21:42:36 +01:00
PlayerGetDestCoords(x, y);
FieldSetDoorOpened(*x, *y);
2021-01-01 21:34:21 +01:00
task->tState = 1;
2018-12-08 21:42:36 +01:00
break;
case 1:
if (WaitForWeatherFadeIn())
2018-12-08 21:42:36 +01:00
{
u8 objEventId;
2019-12-17 09:24:44 +01:00
SetPlayerVisibility(TRUE);
2019-12-21 11:19:27 +01:00
objEventId = GetObjectEventIdByLocalIdAndMap(OBJ_EVENT_ID_PLAYER, 0, 0);
ObjectEventSetHeldMovement(&gObjectEvents[objEventId], MOVEMENT_ACTION_WALK_NORMAL_DOWN);
2021-01-01 21:34:21 +01:00
task->tState = 2;
2018-12-08 21:42:36 +01:00
}
break;
case 2:
2019-12-17 09:24:44 +01:00
if (IsPlayerStandingStill())
2018-12-08 21:42:36 +01:00
{
u8 objEventId;
2018-12-08 21:42:36 +01:00
task->data[1] = FieldAnimateDoorClose(*x, *y);
2019-12-21 11:19:27 +01:00
objEventId = GetObjectEventIdByLocalIdAndMap(OBJ_EVENT_ID_PLAYER, 0, 0);
ObjectEventClearHeldMovementIfFinished(&gObjectEvents[objEventId]);
2021-01-01 21:34:21 +01:00
task->tState = 3;
2018-12-08 21:42:36 +01:00
}
break;
case 3:
if (task->data[1] < 0 || gTasks[task->data[1]].isActive != TRUE)
{
UnfreezeObjectEvents();
2021-01-01 21:34:21 +01:00
task->tState = 4;
2018-12-08 21:42:36 +01:00
}
break;
case 4:
ScriptContext2_Disable();
DestroyTask(taskId);
break;
}
}
2019-12-17 09:24:44 +01:00
static void Task_ExitNonAnimDoor(u8 taskId)
2018-12-08 21:42:36 +01:00
{
struct Task *task = &gTasks[taskId];
s16 *x = &task->data[2];
s16 *y = &task->data[3];
2021-01-01 21:34:21 +01:00
switch (task->tState)
2018-12-08 21:42:36 +01:00
{
case 0:
2019-12-17 09:24:44 +01:00
SetPlayerVisibility(FALSE);
FreezeObjectEvents();
2018-12-08 21:42:36 +01:00
PlayerGetDestCoords(x, y);
2021-01-01 21:34:21 +01:00
task->tState = 1;
2018-12-08 21:42:36 +01:00
break;
case 1:
if (WaitForWeatherFadeIn())
2018-12-08 21:42:36 +01:00
{
u8 objEventId;
2019-12-17 09:24:44 +01:00
SetPlayerVisibility(TRUE);
2019-12-21 11:19:27 +01:00
objEventId = GetObjectEventIdByLocalIdAndMap(OBJ_EVENT_ID_PLAYER, 0, 0);
ObjectEventSetHeldMovement(&gObjectEvents[objEventId], GetWalkNormalMovementAction(GetPlayerFacingDirection()));
2021-01-01 21:34:21 +01:00
task->tState = 2;
2018-12-08 21:42:36 +01:00
}
break;
case 2:
2019-12-17 09:24:44 +01:00
if (IsPlayerStandingStill())
2018-12-08 21:42:36 +01:00
{
UnfreezeObjectEvents();
2021-01-01 21:34:21 +01:00
task->tState = 3;
2018-12-08 21:42:36 +01:00
}
break;
case 3:
ScriptContext2_Disable();
DestroyTask(taskId);
break;
}
}
2019-12-17 09:24:44 +01:00
static void Task_ExitNonDoor(u8 taskId)
2018-12-08 21:42:36 +01:00
{
2021-01-01 21:34:21 +01:00
switch (gTasks[taskId].tState)
2018-12-08 21:42:36 +01:00
{
case 0:
FreezeObjectEvents();
2018-12-08 21:42:36 +01:00
ScriptContext2_Enable();
2021-01-01 21:34:21 +01:00
gTasks[taskId].tState++;
2018-12-08 21:42:36 +01:00
break;
case 1:
if (WaitForWeatherFadeIn())
2018-12-08 21:42:36 +01:00
{
UnfreezeObjectEvents();
2018-12-08 21:42:36 +01:00
ScriptContext2_Disable();
DestroyTask(taskId);
}
break;
}
}
2019-12-17 09:24:44 +01:00
static void Task_WaitForFadeShowStartMenu(u8 taskId)
2018-12-08 21:42:36 +01:00
{
if (WaitForWeatherFadeIn() == TRUE)
2018-12-08 21:42:36 +01:00
{
DestroyTask(taskId);
2019-12-11 09:28:55 +01:00
CreateTask(Task_ShowStartMenu, 80);
2018-12-08 21:42:36 +01:00
}
}
2019-12-17 09:24:44 +01:00
void ReturnToFieldOpenStartMenu(void)
2018-12-08 21:42:36 +01:00
{
2019-12-17 09:24:44 +01:00
FadeInFromBlack();
CreateTask(Task_WaitForFadeShowStartMenu, 0x50);
2018-12-08 21:42:36 +01:00
ScriptContext2_Enable();
}
2019-12-17 09:24:44 +01:00
bool8 FieldCB_ReturnToFieldOpenStartMenu(void)
2018-12-08 21:42:36 +01:00
{
2019-12-17 09:24:44 +01:00
ShowReturnToFieldStartMenu();
2018-12-08 21:42:36 +01:00
return FALSE;
}
2021-01-01 23:02:03 +01:00
static void Task_ReturnToFieldNoScript(u8 taskId)
2018-12-08 21:42:36 +01:00
{
if (WaitForWeatherFadeIn() == 1)
2018-12-08 21:42:36 +01:00
{
ScriptContext2_Disable();
DestroyTask(taskId);
ScriptUnfreezeObjectEvents();
2018-12-08 21:42:36 +01:00
}
}
2021-01-01 23:02:03 +01:00
void FieldCB_ReturnToFieldNoScript(void)
2018-12-08 21:42:36 +01:00
{
ScriptContext2_Enable();
2019-12-17 09:24:44 +01:00
FadeInFromBlack();
2021-01-01 23:02:03 +01:00
CreateTask(Task_ReturnToFieldNoScript, 10);
2018-12-08 21:42:36 +01:00
}
2021-01-01 23:02:03 +01:00
void FieldCB_ReturnToFieldNoScriptCheckMusic(void)
2018-12-08 21:42:36 +01:00
{
ScriptContext2_Enable();
Overworld_PlaySpecialMapMusic();
2019-12-17 09:24:44 +01:00
FadeInFromBlack();
2021-01-01 23:02:03 +01:00
CreateTask(Task_ReturnToFieldNoScript, 10);
2018-12-08 21:42:36 +01:00
}
2018-12-08 22:05:11 +01:00
static bool32 PaletteFadeActive(void)
2018-12-08 21:42:36 +01:00
{
return gPaletteFade.active;
}
static bool32 WaitForWeatherFadeIn(void)
2018-12-08 21:42:36 +01:00
{
if (IsWeatherNotFadingIn() == TRUE)
return TRUE;
else
return FALSE;
}
2018-12-28 22:11:15 +01:00
void DoWarp(void)
2018-12-08 21:42:36 +01:00
{
ScriptContext2_Enable();
TryFadeOutOldMapMusic();
2019-12-17 09:24:44 +01:00
WarpFadeOutScreen();
PlayRainStoppingSoundEffect();
2020-08-21 00:02:00 +02:00
PlaySE(SE_EXIT);
2019-12-17 09:24:44 +01:00
gFieldCallback = FieldCB_DefaultWarpExit;
CreateTask(Task_WarpAndLoadMap, 10);
2018-12-08 21:42:36 +01:00
}
2018-12-28 22:11:15 +01:00
void DoDiveWarp(void)
2018-12-08 21:42:36 +01:00
{
ScriptContext2_Enable();
TryFadeOutOldMapMusic();
2019-12-17 09:24:44 +01:00
WarpFadeOutScreen();
PlayRainStoppingSoundEffect();
2019-12-17 09:24:44 +01:00
gFieldCallback = FieldCB_DefaultWarpExit;
CreateTask(Task_WarpAndLoadMap, 10);
2018-12-08 21:42:36 +01:00
}
2019-12-17 09:24:44 +01:00
void DoSootopolisLegendWarp(void)
2018-12-08 21:42:36 +01:00
{
ScriptContext2_Enable();
TryFadeOutOldMapMusic();
FadeScreen(FADE_TO_WHITE, 8);
PlayRainStoppingSoundEffect();
2019-12-17 09:24:44 +01:00
gFieldCallback = FieldCB_WarpExitFadeFromWhite;
CreateTask(Task_WarpAndLoadMap, 10);
2018-12-08 21:42:36 +01:00
}
2018-12-28 22:11:15 +01:00
void DoDoorWarp(void)
2018-12-08 21:42:36 +01:00
{
ScriptContext2_Enable();
2019-12-17 09:24:44 +01:00
gFieldCallback = FieldCB_DefaultWarpExit;
CreateTask(Task_DoDoorWarp, 10);
2018-12-08 21:42:36 +01:00
}
2018-12-28 22:11:15 +01:00
void DoFallWarp(void)
2018-12-08 21:42:36 +01:00
{
2018-12-28 22:11:15 +01:00
DoDiveWarp();
2019-12-17 09:24:44 +01:00
gFieldCallback = FieldCB_FallWarpExit;
2018-12-08 21:42:36 +01:00
}
2019-12-17 09:24:44 +01:00
void DoEscalatorWarp(u8 metatileBehavior)
2018-12-08 21:42:36 +01:00
{
ScriptContext2_Enable();
2019-12-17 09:24:44 +01:00
StartEscalatorWarp(metatileBehavior, 10);
2018-12-08 21:42:36 +01:00
}
2019-12-17 09:24:44 +01:00
void DoLavaridgeGymB1FWarp(void)
2018-12-08 21:42:36 +01:00
{
ScriptContext2_Enable();
2019-12-17 09:24:44 +01:00
StartLavaridgeGymB1FWarp(10);
2018-12-08 21:42:36 +01:00
}
2019-12-17 09:24:44 +01:00
void DoLavaridgeGym1FWarp(void)
2018-12-08 21:42:36 +01:00
{
ScriptContext2_Enable();
2019-12-17 09:24:44 +01:00
StartLavaridgeGym1FWarp(10);
2018-12-08 21:42:36 +01:00
}
2021-01-01 21:34:21 +01:00
// DoSpinEnterWarp but with a fade out
// Screen fades out to exit current map, player spins down from top to enter new map
// Used by teleporting tiles, e.g. in Aqua Hideout (For the move Teleport see FldEff_TeleportWarpOut)
2020-06-29 23:24:17 +02:00
void DoTeleportTileWarp(void)
2018-12-08 21:42:36 +01:00
{
ScriptContext2_Enable();
TryFadeOutOldMapMusic();
2019-12-17 09:24:44 +01:00
WarpFadeOutScreen();
2020-08-21 00:02:00 +02:00
PlaySE(SE_WARP_IN);
2019-12-17 09:24:44 +01:00
CreateTask(Task_WarpAndLoadMap, 10);
2021-01-01 21:34:21 +01:00
gFieldCallback = FieldCB_SpinEnterWarp;
2018-12-08 21:42:36 +01:00
}
void DoMossdeepGymWarp(void)
2018-12-08 21:42:36 +01:00
{
SetObjectEventLoadFlag(SKIP_OBJECT_EVENT_LOAD);
2018-12-08 21:42:36 +01:00
ScriptContext2_Enable();
SaveObjectEvents();
2018-12-08 21:42:36 +01:00
TryFadeOutOldMapMusic();
2019-12-17 09:24:44 +01:00
WarpFadeOutScreen();
2020-08-21 00:02:00 +02:00
PlaySE(SE_WARP_IN);
2019-12-17 09:24:44 +01:00
CreateTask(Task_WarpAndLoadMap, 10);
gFieldCallback = FieldCB_MossdeepGymWarpExit;
2018-12-08 21:42:36 +01:00
}
2019-12-17 09:24:44 +01:00
void DoPortholeWarp(void)
2018-12-08 21:42:36 +01:00
{
ScriptContext2_Enable();
2019-12-17 09:24:44 +01:00
WarpFadeOutScreen();
CreateTask(Task_WarpAndLoadMap, 10);
gFieldCallback = FieldCB_ShowPortholeView;
2018-12-08 21:42:36 +01:00
}
static void Task_DoCableClubWarp(u8 taskId)
2018-12-08 21:42:36 +01:00
{
struct Task *task = &gTasks[taskId];
switch (task->tState)
2018-12-08 21:42:36 +01:00
{
case 0:
ScriptContext2_Enable();
task->tState++;
2018-12-08 21:42:36 +01:00
break;
case 1:
if (!PaletteFadeActive() && BGMusicStopped())
task->tState++;
2018-12-08 21:42:36 +01:00
break;
case 2:
WarpIntoMap();
2019-12-17 09:24:44 +01:00
SetMainCallback2(CB2_ReturnToFieldCableClub);
2018-12-08 21:42:36 +01:00
DestroyTask(taskId);
break;
}
}
2019-12-17 09:24:44 +01:00
void DoCableClubWarp(void)
2018-12-08 21:42:36 +01:00
{
ScriptContext2_Enable();
TryFadeOutOldMapMusic();
2019-12-17 09:24:44 +01:00
WarpFadeOutScreen();
2020-08-21 00:02:00 +02:00
PlaySE(SE_EXIT);
CreateTask(Task_DoCableClubWarp, 10);
2018-12-08 21:42:36 +01:00
}
static void Task_ReturnToWorldFromLinkRoom(u8 taskId)
2018-12-08 21:42:36 +01:00
{
s16 *data = gTasks[taskId].data;
2021-01-01 21:34:21 +01:00
switch (tState)
2018-12-08 21:42:36 +01:00
{
case 0:
ClearLinkCallback_2();
FadeScreen(FADE_TO_BLACK, 0);
TryFadeOutOldMapMusic();
2020-08-21 00:02:00 +02:00
PlaySE(SE_EXIT);
2021-01-01 21:34:21 +01:00
tState++;
2018-12-08 21:42:36 +01:00
break;
case 1:
if (!PaletteFadeActive() && BGMusicStopped())
{
2020-08-13 09:09:47 +02:00
SetCloseLinkCallback();
2021-01-01 21:34:21 +01:00
tState++;
2018-12-08 21:42:36 +01:00
}
break;
case 2:
if (!gReceivedRemoteLinkPlayers)
{
WarpIntoMap();
SetMainCallback2(CB2_LoadMap);
DestroyTask(taskId);
}
break;
}
}
2019-10-11 10:14:09 +02:00
void ReturnFromLinkRoom(void)
2018-12-08 21:42:36 +01:00
{
CreateTask(Task_ReturnToWorldFromLinkRoom, 10);
2018-12-08 21:42:36 +01:00
}
2019-12-17 09:24:44 +01:00
static void Task_WarpAndLoadMap(u8 taskId)
2018-12-08 21:42:36 +01:00
{
struct Task *task = &gTasks[taskId];
2021-01-01 21:34:21 +01:00
switch (task->tState)
2018-12-08 21:42:36 +01:00
{
case 0:
FreezeObjectEvents();
2018-12-08 21:42:36 +01:00
ScriptContext2_Enable();
2021-01-01 21:34:21 +01:00
task->tState++;
2018-12-08 21:42:36 +01:00
break;
case 1:
if (!PaletteFadeActive())
{
if (task->data[1] == 0)
{
ClearMirageTowerPulseBlendEffect();
2018-12-08 21:42:36 +01:00
task->data[1] = 1;
}
if (BGMusicStopped())
2021-01-01 21:34:21 +01:00
task->tState++;
2018-12-08 21:42:36 +01:00
}
break;
case 2:
WarpIntoMap();
SetMainCallback2(CB2_LoadMap);
DestroyTask(taskId);
break;
}
}
2019-12-17 09:24:44 +01:00
static void Task_DoDoorWarp(u8 taskId)
2018-12-08 21:42:36 +01:00
{
struct Task *task = &gTasks[taskId];
s16 *x = &task->data[2];
s16 *y = &task->data[3];
2021-01-01 21:34:21 +01:00
switch (task->tState)
2018-12-08 21:42:36 +01:00
{
case 0:
FreezeObjectEvents();
2018-12-08 21:42:36 +01:00
PlayerGetDestCoords(x, y);
PlaySE(GetDoorSoundEffect(*x, *y - 1));
task->data[1] = FieldAnimateDoorOpen(*x, *y - 1);
2021-01-01 21:34:21 +01:00
task->tState = 1;
2018-12-08 21:42:36 +01:00
break;
case 1:
if (task->data[1] < 0 || gTasks[task->data[1]].isActive != TRUE)
{
u8 objEventId;
2019-12-21 11:19:27 +01:00
objEventId = GetObjectEventIdByLocalIdAndMap(OBJ_EVENT_ID_PLAYER, 0, 0);
ObjectEventClearHeldMovementIfActive(&gObjectEvents[objEventId]);
2019-12-21 11:19:27 +01:00
objEventId = GetObjectEventIdByLocalIdAndMap(OBJ_EVENT_ID_PLAYER, 0, 0);
ObjectEventSetHeldMovement(&gObjectEvents[objEventId], MOVEMENT_ACTION_WALK_NORMAL_UP);
2021-01-01 21:34:21 +01:00
task->tState = 2;
2018-12-08 21:42:36 +01:00
}
break;
case 2:
2019-12-17 09:24:44 +01:00
if (IsPlayerStandingStill())
2018-12-08 21:42:36 +01:00
{
u8 objEventId;
2018-12-08 21:42:36 +01:00
task->data[1] = FieldAnimateDoorClose(*x, *y - 1);
2019-12-21 11:19:27 +01:00
objEventId = GetObjectEventIdByLocalIdAndMap(OBJ_EVENT_ID_PLAYER, 0, 0);
ObjectEventClearHeldMovementIfFinished(&gObjectEvents[objEventId]);
2019-12-17 09:24:44 +01:00
SetPlayerVisibility(FALSE);
2021-01-01 21:34:21 +01:00
task->tState = 3;
2018-12-08 21:42:36 +01:00
}
break;
case 3:
if (task->data[1] < 0 || gTasks[task->data[1]].isActive != TRUE)
{
2021-01-01 21:34:21 +01:00
task->tState = 4;
2018-12-08 21:42:36 +01:00
}
break;
case 4:
TryFadeOutOldMapMusic();
2019-12-17 09:24:44 +01:00
WarpFadeOutScreen();
PlayRainStoppingSoundEffect();
2021-01-01 21:34:21 +01:00
task->tState = 0;
2019-12-17 09:24:44 +01:00
task->func = Task_WarpAndLoadMap;
2018-12-08 21:42:36 +01:00
break;
}
}
static void Task_DoContestHallWarp(u8 taskId)
2018-12-08 21:42:36 +01:00
{
struct Task *task = &gTasks[taskId];
2021-01-01 21:34:21 +01:00
switch (task->tState)
2018-12-08 21:42:36 +01:00
{
case 0:
FreezeObjectEvents();
2018-12-08 21:42:36 +01:00
ScriptContext2_Enable();
2021-01-01 21:34:21 +01:00
task->tState++;
2018-12-08 21:42:36 +01:00
break;
case 1:
if (!PaletteFadeActive() && BGMusicStopped())
{
2021-01-01 21:34:21 +01:00
task->tState++;
2018-12-08 21:42:36 +01:00
}
break;
case 2:
WarpIntoMap();
SetMainCallback2(CB2_ReturnToFieldContestHall);
2018-12-08 21:42:36 +01:00
DestroyTask(taskId);
break;
}
}
2019-11-11 03:54:00 +01:00
void DoContestHallWarp(void)
2018-12-08 21:42:36 +01:00
{
ScriptContext2_Enable();
TryFadeOutOldMapMusic();
2019-12-17 09:24:44 +01:00
WarpFadeOutScreen();
PlayRainStoppingSoundEffect();
2020-08-21 00:02:00 +02:00
PlaySE(SE_EXIT);
2019-12-17 09:24:44 +01:00
gFieldCallback = FieldCB_WarpExitFadeFromBlack;
CreateTask(Task_DoContestHallWarp, 10);
2018-12-08 21:42:36 +01:00
}
2018-12-08 22:05:11 +01:00
static void SetFlashScanlineEffectWindowBoundary(u16 *dest, u32 y, s32 left, s32 right)
2018-12-08 21:42:36 +01:00
{
if (y <= 160)
{
if (left < 0)
left = 0;
if (left > 255)
left = 255;
if (right < 0)
right = 0;
if (right > 255)
right = 255;
dest[y] = (left << 8) | right;
}
}
2018-12-08 22:05:11 +01:00
static void SetFlashScanlineEffectWindowBoundaries(u16 *dest, s32 centerX, s32 centerY, s32 radius)
2018-12-08 21:42:36 +01:00
{
s32 r = radius;
s32 v2 = radius;
s32 v3 = 0;
while (r >= v3)
{
SetFlashScanlineEffectWindowBoundary(dest, centerY - v3, centerX - r, centerX + r);
SetFlashScanlineEffectWindowBoundary(dest, centerY + v3, centerX - r, centerX + r);
SetFlashScanlineEffectWindowBoundary(dest, centerY - r, centerX - v3, centerX + v3);
SetFlashScanlineEffectWindowBoundary(dest, centerY + r, centerX - v3, centerX + v3);
v2 -= (v3 * 2) - 1;
v3++;
if (v2 < 0)
{
v2 += 2 * (r - 1);
r--;
}
}
}
2019-11-01 08:41:55 +01:00
static void SetOrbFlashScanlineEffectWindowBoundary(u16 *dest, u32 y, s32 left, s32 right)
2018-12-08 21:42:36 +01:00
{
if (y <= 160)
{
if (left < 0)
left = 0;
if (left > 240)
left = 240;
if (right < 0)
right = 0;
if (right > 240)
right = 240;
dest[y] = (left << 8) | right;
}
}
2019-11-01 08:41:55 +01:00
static void SetOrbFlashScanlineEffectWindowBoundaries(u16 *dest, s32 centerX, s32 centerY, s32 radius)
2018-12-08 21:42:36 +01:00
{
s32 r = radius;
s32 v2 = radius;
s32 v3 = 0;
while (r >= v3)
{
2019-11-01 08:41:55 +01:00
SetOrbFlashScanlineEffectWindowBoundary(dest, centerY - v3, centerX - r, centerX + r);
SetOrbFlashScanlineEffectWindowBoundary(dest, centerY + v3, centerX - r, centerX + r);
SetOrbFlashScanlineEffectWindowBoundary(dest, centerY - r, centerX - v3, centerX + v3);
SetOrbFlashScanlineEffectWindowBoundary(dest, centerY + r, centerX - v3, centerX + v3);
2018-12-08 21:42:36 +01:00
v2 -= (v3 * 2) - 1;
v3++;
if (v2 < 0)
{
v2 += 2 * (r - 1);
r--;
}
}
}
#define tFlashCenterX data[1]
#define tFlashCenterY data[2]
#define tCurFlashRadius data[3]
#define tDestFlashRadius data[4]
#define tFlashRadiusDelta data[5]
#define tClearScanlineEffect data[6]
2018-12-08 22:05:11 +01:00
static void UpdateFlashLevelEffect(u8 taskId)
2018-12-08 21:42:36 +01:00
{
s16 *data = gTasks[taskId].data;
2021-01-01 21:34:21 +01:00
switch (tState)
2018-12-08 21:42:36 +01:00
{
case 0:
SetFlashScanlineEffectWindowBoundaries(gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer], tFlashCenterX, tFlashCenterY, tCurFlashRadius);
2021-01-01 21:34:21 +01:00
tState = 1;
2018-12-08 21:42:36 +01:00
break;
case 1:
SetFlashScanlineEffectWindowBoundaries(gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer], tFlashCenterX, tFlashCenterY, tCurFlashRadius);
2021-01-01 21:34:21 +01:00
tState = 0;
2018-12-08 21:42:36 +01:00
tCurFlashRadius += tFlashRadiusDelta;
if (tCurFlashRadius > tDestFlashRadius)
{
if (tClearScanlineEffect == 1)
{
ScanlineEffect_Stop();
2021-01-01 21:34:21 +01:00
tState = 2;
2018-12-08 21:42:36 +01:00
}
else
{
DestroyTask(taskId);
}
}
break;
case 2:
ScanlineEffect_Clear();
DestroyTask(taskId);
break;
}
}
2019-11-01 08:41:55 +01:00
static void UpdateOrbFlashEffect(u8 taskId)
2018-12-08 21:42:36 +01:00
{
s16 *data = gTasks[taskId].data;
2021-01-01 21:34:21 +01:00
switch (tState)
2018-12-08 21:42:36 +01:00
{
case 0:
2019-11-01 08:41:55 +01:00
SetOrbFlashScanlineEffectWindowBoundaries(gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer], tFlashCenterX, tFlashCenterY, tCurFlashRadius);
2021-01-01 21:34:21 +01:00
tState = 1;
2018-12-08 21:42:36 +01:00
break;
case 1:
2019-11-01 08:41:55 +01:00
SetOrbFlashScanlineEffectWindowBoundaries(gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer], tFlashCenterX, tFlashCenterY, tCurFlashRadius);
2021-01-01 21:34:21 +01:00
tState = 0;
2018-12-08 21:42:36 +01:00
tCurFlashRadius += tFlashRadiusDelta;
if (tCurFlashRadius > tDestFlashRadius)
{
if (tClearScanlineEffect == 1)
{
ScanlineEffect_Stop();
2021-01-01 21:34:21 +01:00
tState = 2;
2018-12-08 21:42:36 +01:00
}
else
{
DestroyTask(taskId);
}
}
break;
case 2:
ScanlineEffect_Clear();
DestroyTask(taskId);
break;
}
}
2021-01-01 19:34:25 +01:00
static void Task_WaitForFlashUpdate(u8 taskId)
2018-12-08 21:42:36 +01:00
{
if (!FuncIsActiveTask(UpdateFlashLevelEffect))
{
EnableBothScriptContexts();
DestroyTask(taskId);
}
}
2021-01-01 19:34:25 +01:00
static void StartWaitForFlashUpdate(void)
2018-12-08 21:42:36 +01:00
{
2021-01-01 19:34:25 +01:00
if (!FuncIsActiveTask(Task_WaitForFlashUpdate))
CreateTask(Task_WaitForFlashUpdate, 80);
2018-12-08 21:42:36 +01:00
}
2021-01-01 19:34:25 +01:00
static u8 StartUpdateFlashLevelEffect(s32 centerX, s32 centerY, s32 initialFlashRadius, s32 destFlashRadius, s32 clearScanlineEffect, u8 delta)
2018-12-08 21:42:36 +01:00
{
u8 taskId = CreateTask(UpdateFlashLevelEffect, 80);
s16 *data = gTasks[taskId].data;
tCurFlashRadius = initialFlashRadius;
tDestFlashRadius = destFlashRadius;
tFlashCenterX = centerX;
tFlashCenterY = centerY;
tClearScanlineEffect = clearScanlineEffect;
if (initialFlashRadius < destFlashRadius)
tFlashRadiusDelta = delta;
else
tFlashRadiusDelta = -delta;
return taskId;
}
2021-01-01 19:34:25 +01:00
static u8 StartUpdateOrbFlashEffect(s32 centerX, s32 centerY, s32 initialFlashRadius, s32 destFlashRadius, s32 clearScanlineEffect, u8 delta)
2018-12-08 21:42:36 +01:00
{
2019-11-01 08:41:55 +01:00
u8 taskId = CreateTask(UpdateOrbFlashEffect, 80);
2018-12-08 21:42:36 +01:00
s16 *data = gTasks[taskId].data;
tCurFlashRadius = initialFlashRadius;
tDestFlashRadius = destFlashRadius;
tFlashCenterX = centerX;
tFlashCenterY = centerY;
tClearScanlineEffect = clearScanlineEffect;
if (initialFlashRadius < destFlashRadius)
tFlashRadiusDelta = delta;
else
tFlashRadiusDelta = -delta;
return taskId;
}
#undef tCurFlashRadius
#undef tDestFlashRadius
#undef tFlashRadiusDelta
#undef tClearScanlineEffect
2021-01-01 19:34:25 +01:00
// A higher flashLevel value is a smaller flash radius (more darkness). 0 is full brightness
2019-10-11 23:25:07 +02:00
void AnimateFlash(u8 flashLevel)
2018-12-08 21:42:36 +01:00
{
u8 curFlashLevel = Overworld_GetFlashLevel();
2021-01-01 19:34:25 +01:00
bool8 fullBrightness = FALSE;
2018-12-08 21:42:36 +01:00
if (!flashLevel)
2021-01-01 19:34:25 +01:00
fullBrightness = TRUE;
StartUpdateFlashLevelEffect(DISPLAY_WIDTH / 2, DISPLAY_HEIGHT / 2, sFlashLevelPixelRadii[curFlashLevel], sFlashLevelPixelRadii[flashLevel], fullBrightness, 1);
StartWaitForFlashUpdate();
2018-12-08 21:42:36 +01:00
ScriptContext2_Enable();
}
void WriteFlashScanlineEffectBuffer(u8 flashLevel)
{
if (flashLevel)
{
2020-06-29 22:53:38 +02:00
SetFlashScanlineEffectWindowBoundaries(&gScanlineEffectRegBuffers[0][0], DISPLAY_WIDTH / 2, DISPLAY_HEIGHT / 2, sFlashLevelPixelRadii[flashLevel]);
2018-12-08 21:42:36 +01:00
CpuFastSet(&gScanlineEffectRegBuffers[0], &gScanlineEffectRegBuffers[1], 480);
}
}
2019-02-07 03:01:29 +01:00
void WriteBattlePyramidViewScanlineEffectBuffer(void)
2018-12-08 21:42:36 +01:00
{
2020-06-29 22:53:38 +02:00
SetFlashScanlineEffectWindowBoundaries(&gScanlineEffectRegBuffers[0][0], DISPLAY_WIDTH / 2, DISPLAY_HEIGHT / 2, gSaveBlock2Ptr->frontier.pyramidLightRadius);
2018-12-08 21:42:36 +01:00
CpuFastSet(&gScanlineEffectRegBuffers[0], &gScanlineEffectRegBuffers[1], 480);
}
2021-01-01 21:34:21 +01:00
static void Task_SpinEnterWarp(u8 taskId)
2018-12-08 21:42:36 +01:00
{
2021-01-01 21:34:21 +01:00
switch (gTasks[taskId].tState)
2018-12-08 21:42:36 +01:00
{
case 0:
FreezeObjectEvents();
2018-12-08 21:42:36 +01:00
ScriptContext2_Enable();
2021-01-01 21:34:21 +01:00
DoPlayerSpinEntrance();
gTasks[taskId].tState++;
2018-12-08 21:42:36 +01:00
break;
case 1:
2021-01-01 21:34:21 +01:00
if (WaitForWeatherFadeIn() && IsPlayerSpinEntranceActive() != TRUE)
2018-12-08 21:42:36 +01:00
{
UnfreezeObjectEvents();
2018-12-08 21:42:36 +01:00
ScriptContext2_Disable();
DestroyTask(taskId);
}
break;
}
}
2021-01-01 21:34:21 +01:00
static void Task_SpinExitWarp(u8 taskId)
2018-12-08 21:42:36 +01:00
{
struct Task *task = &gTasks[taskId];
2021-01-01 21:34:21 +01:00
switch (task->tState)
2018-12-08 21:42:36 +01:00
{
case 0:
FreezeObjectEvents();
2018-12-08 21:42:36 +01:00
ScriptContext2_Enable();
2020-08-21 00:02:00 +02:00
PlaySE(SE_WARP_IN);
2021-01-01 21:34:21 +01:00
DoPlayerSpinExit();
task->tState++;
2018-12-08 21:42:36 +01:00
break;
case 1:
2021-01-01 21:34:21 +01:00
if (!IsPlayerSpinExitActive())
2018-12-08 21:42:36 +01:00
{
2019-12-17 09:24:44 +01:00
WarpFadeOutScreen();
2021-01-01 21:34:21 +01:00
task->tState++;
2018-12-08 21:42:36 +01:00
}
break;
case 2:
if (!PaletteFadeActive() && BGMusicStopped())
2021-01-01 21:34:21 +01:00
task->tState++;
2018-12-08 21:42:36 +01:00
break;
case 3:
WarpIntoMap();
SetMainCallback2(CB2_LoadMap);
DestroyTask(taskId);
break;
}
}
2021-01-01 21:34:21 +01:00
// Only called by an unused function
// DoTeleportTileWarp is used instead
void DoSpinEnterWarp(void)
2018-12-08 21:42:36 +01:00
{
ScriptContext2_Enable();
2019-12-17 09:24:44 +01:00
CreateTask(Task_WarpAndLoadMap, 10);
2021-01-01 21:34:21 +01:00
gFieldCallback = FieldCB_SpinEnterWarp;
2018-12-08 21:42:36 +01:00
}
2021-01-01 21:34:21 +01:00
// Opposite of DoSpinEnterWarp / DoTeleportTileWarp
// Player exits current map by spinning up offscreen, enters new map with a fade in
void DoSpinExitWarp(void)
2018-12-08 21:42:36 +01:00
{
ScriptContext2_Enable();
2019-12-17 09:24:44 +01:00
gFieldCallback = FieldCB_DefaultWarpExit;
2021-01-01 21:34:21 +01:00
CreateTask(Task_SpinExitWarp, 10);
2018-12-08 21:42:36 +01:00
}
2019-11-01 08:41:55 +01:00
static void LoadOrbEffectPalette(bool8 blueOrb)
2018-12-08 21:42:36 +01:00
{
int i;
u16 color[1];
2019-11-01 08:41:55 +01:00
if (!blueOrb)
2018-12-09 12:16:01 +01:00
color[0] = RGB_RED;
2018-12-08 21:42:36 +01:00
else
2018-12-09 12:16:01 +01:00
color[0] = RGB_BLUE;
2018-12-08 21:42:36 +01:00
for (i = 0; i < 16; i++)
{
LoadPalette(color, 0xF0 + i, 2);
}
}
2019-11-01 08:41:55 +01:00
static bool8 sub_80B02C8(u16 shakeDir)
2018-12-08 21:42:36 +01:00
{
u8 lo = REG_BLDALPHA & 0xFF;
u8 hi = REG_BLDALPHA >> 8;
2019-11-01 08:41:55 +01:00
if (shakeDir != 0)
2018-12-08 21:42:36 +01:00
{
if (lo)
{
lo--;
}
}
else
{
if (hi < 0x10)
{
hi++;
}
}
2018-12-09 12:16:01 +01:00
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(lo, hi));
2018-12-08 21:42:36 +01:00
if (lo == 0 && hi == 0x10)
return TRUE;
else
return FALSE;
}
2019-11-01 08:41:55 +01:00
#define tBlueOrb data[1]
#define tCenterX data[2]
#define tCenterY data[3]
#define tShakeDelay data[4]
#define tShakeDir data[5]
#define tDispCnt data[6]
#define tBldCnt data[7]
#define tBldAlpha data[8]
#define tWinIn data[9]
#define tWinOut data[10]
static void Task_OrbEffect(u8 taskId)
2018-12-08 21:42:36 +01:00
{
s16 *data = gTasks[taskId].data;
2019-11-01 08:41:55 +01:00
switch (tState)
2018-12-08 21:42:36 +01:00
{
case 0:
2019-11-01 08:41:55 +01:00
tDispCnt = REG_DISPCNT;
tBldCnt = REG_BLDCNT;
tBldAlpha = REG_BLDALPHA;
tWinIn = REG_WININ;
tWinOut = REG_WINOUT;
2018-12-08 21:42:36 +01:00
ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN1_ON);
2019-11-01 08:41:55 +01:00
SetGpuRegBits(REG_OFFSET_BLDCNT, gOrbEffectBackgroundLayerFlags[0]);
2018-12-09 12:16:01 +01:00
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(12, 7));
SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR);
SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG1 | WINOUT_WIN01_BG2 | WINOUT_WIN01_BG3 | WINOUT_WIN01_OBJ);
2019-10-26 03:55:01 +02:00
SetBgTilemapPalette(0, 0, 0, 0x1E, 0x14, 0xF);
2020-05-14 10:37:09 +02:00
ScheduleBgCopyTilemapToVram(0);
2019-11-01 08:41:55 +01:00
SetOrbFlashScanlineEffectWindowBoundaries(&gScanlineEffectRegBuffers[0][0], tCenterX, tCenterY, 1);
2018-12-08 21:42:36 +01:00
CpuFastSet(&gScanlineEffectRegBuffers[0], &gScanlineEffectRegBuffers[1], 480);
ScanlineEffect_SetParams(sFlashEffectParams);
2019-11-01 08:41:55 +01:00
tState = 1;
2018-12-08 21:42:36 +01:00
break;
case 1:
2019-04-08 00:31:01 +02:00
sub_8199DF0(0, PIXEL_FILL(1), 0, 1);
2019-11-01 08:41:55 +01:00
LoadOrbEffectPalette(tBlueOrb);
2021-01-01 19:34:25 +01:00
StartUpdateOrbFlashEffect(tCenterX, tCenterY, 1, 160, 1, 2);
2019-11-01 08:41:55 +01:00
tState = 2;
2018-12-08 21:42:36 +01:00
break;
case 2:
2019-11-01 08:41:55 +01:00
if (!FuncIsActiveTask(UpdateOrbFlashEffect))
2018-12-08 21:42:36 +01:00
{
EnableBothScriptContexts();
2019-11-01 08:41:55 +01:00
tState = 3;
2018-12-08 21:42:36 +01:00
}
break;
case 3:
InstallCameraPanAheadCallback();
SetCameraPanningCallback(NULL);
2019-11-01 08:41:55 +01:00
tShakeDir = 0;
tShakeDelay = 4;
tState = 4;
2018-12-08 21:42:36 +01:00
break;
case 4:
2019-11-01 08:41:55 +01:00
if (--tShakeDelay == 0)
2018-12-08 21:42:36 +01:00
{
s32 panning;
2019-11-01 08:41:55 +01:00
tShakeDelay = 4;
tShakeDir ^= 1;
if (tShakeDir)
2018-12-08 21:42:36 +01:00
panning = 4;
else
panning = -4;
SetCameraPanning(0, panning);
}
break;
case 6:
InstallCameraPanAheadCallback();
2019-11-01 08:41:55 +01:00
tShakeDelay = 8;
tState = 7;
2018-12-08 21:42:36 +01:00
break;
case 7:
2019-11-01 08:41:55 +01:00
if (--tShakeDelay == 0)
2018-12-08 21:42:36 +01:00
{
2019-11-01 08:41:55 +01:00
tShakeDelay = 8;
tShakeDir ^= 1;
if (sub_80B02C8(tShakeDir) == TRUE)
2018-12-08 21:42:36 +01:00
{
2019-11-01 08:41:55 +01:00
tState = 5;
2019-04-08 00:31:01 +02:00
sub_8199DF0(0, PIXEL_FILL(0), 0, 1);
2018-12-08 21:42:36 +01:00
}
}
break;
case 5:
SetGpuReg(REG_OFFSET_WIN0H, 255);
2019-11-01 08:41:55 +01:00
SetGpuReg(REG_OFFSET_DISPCNT, tDispCnt);
SetGpuReg(REG_OFFSET_BLDCNT, tBldCnt);
SetGpuReg(REG_OFFSET_BLDALPHA, tBldAlpha);
SetGpuReg(REG_OFFSET_WININ, tWinIn);
SetGpuReg(REG_OFFSET_WINOUT, tWinOut);
2018-12-08 21:42:36 +01:00
EnableBothScriptContexts();
DestroyTask(taskId);
break;
}
}
2019-11-01 08:41:55 +01:00
void DoOrbEffect(void)
2018-12-08 21:42:36 +01:00
{
2019-11-01 08:41:55 +01:00
u8 taskId = CreateTask(Task_OrbEffect, 80);
2018-12-08 21:42:36 +01:00
s16 *data = gTasks[taskId].data;
if (gSpecialVar_Result == 0)
{
2019-11-01 08:41:55 +01:00
tBlueOrb = FALSE;
tCenterX = 104;
2018-12-08 21:42:36 +01:00
}
else if (gSpecialVar_Result == 1)
{
2019-11-01 08:41:55 +01:00
tBlueOrb = TRUE;
tCenterX = 136;
2018-12-08 21:42:36 +01:00
}
else if (gSpecialVar_Result == 2)
{
2019-11-01 08:41:55 +01:00
tBlueOrb = FALSE;
tCenterX = 120;
2018-12-08 21:42:36 +01:00
}
else
{
2019-11-01 08:41:55 +01:00
tBlueOrb = TRUE;
tCenterX = 120;
2018-12-08 21:42:36 +01:00
}
2019-11-01 08:41:55 +01:00
tCenterY = 80;
2018-12-08 21:42:36 +01:00
}
2019-11-01 08:41:55 +01:00
void FadeOutOrbEffect(void)
2018-12-08 21:42:36 +01:00
{
2019-11-01 08:41:55 +01:00
u8 taskId = FindTaskIdByFunc(Task_OrbEffect);
gTasks[taskId].tState = 6;
2018-12-08 21:42:36 +01:00
}
2019-11-01 08:41:55 +01:00
#undef tBlueOrb
#undef tCenterX
#undef tCenterY
#undef tShakeDelay
#undef tShakeDir
#undef tDispCnt
#undef tBldCnt
#undef tBldAlpha
#undef tWinIn
#undef tWinOut
2019-10-07 02:04:30 +02:00
void Script_FadeOutMapMusic(void)
2018-12-08 21:42:36 +01:00
{
Overworld_FadeOutMapMusic();
2019-10-07 02:04:30 +02:00
CreateTask(Task_EnableScriptAfterMusicFade, 80);
2018-12-08 21:42:36 +01:00
}
2019-10-07 02:04:30 +02:00
static void Task_EnableScriptAfterMusicFade(u8 taskId)
2018-12-08 21:42:36 +01:00
{
if (BGMusicStopped() == TRUE)
{
DestroyTask(taskId);
EnableBothScriptContexts();
}
}