summaryrefslogtreecommitdiff
path: root/src/fldeff_flash.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fldeff_flash.c')
-rw-r--r--src/fldeff_flash.c479
1 files changed, 479 insertions, 0 deletions
diff --git a/src/fldeff_flash.c b/src/fldeff_flash.c
new file mode 100644
index 000000000..58cb4c251
--- /dev/null
+++ b/src/fldeff_flash.c
@@ -0,0 +1,479 @@
+#include "global.h"
+#include "gflib.h"
+#include "event_data.h"
+#include "event_scripts.h"
+#include "fldeff.h"
+#include "field_effect.h"
+#include "map_preview_screen.h"
+#include "overworld.h"
+#include "party_menu.h"
+#include "script.h"
+#include "constants/songs.h"
+#include "constants/map_types.h"
+
+struct FlashStruct
+{
+ u8 fromType;
+ u8 toType;
+ bool8 isEnter;
+ bool8 isExit;
+ void (*func1)(void);
+ void (*func2)(u8 mapSecId);
+};
+
+static void FieldCallback_Flash(void);
+static void FldEff_UseFlash(void);
+static bool8 TryDoMapTransition(void);
+static void FlashTransition_Exit(void);
+static void Task_FlashTransition_Exit_0(u8 taskId);
+static void Task_FlashTransition_Exit_1(u8 taskId);
+static void Task_FlashTransition_Exit_2(u8 taskId);
+static void Task_FlashTransition_Exit_3(u8 taskId);
+static void Task_FlashTransition_Exit_4(u8 taskId);
+static void FlashTransition_Enter(void);
+static void Task_FlashTransition_Enter_0(u8 taskId);
+static void Task_FlashTransition_Enter_1(u8 taskId);
+static void Task_FlashTransition_Enter_2(u8 taskId);
+static void Task_FlashTransition_Enter_3(u8 taskId);
+static void RunMapPreviewScreen(u8 mapsecId);
+static void Task_MapPreviewScreen_0(u8 taskId);
+
+static const struct FlashStruct sTransitionTypes[] = {
+ {
+ .fromType = MAP_TYPE_TOWN,
+ .toType = MAP_TYPE_UNDERGROUND,
+ .isEnter = TRUE,
+ .isExit = FALSE,
+ .func1 = FlashTransition_Enter,
+ .func2 = RunMapPreviewScreen
+ }, {
+ .fromType = MAP_TYPE_CITY,
+ .toType = MAP_TYPE_UNDERGROUND,
+ .isEnter = TRUE,
+ .isExit = FALSE,
+ .func1 = FlashTransition_Enter,
+ .func2 = RunMapPreviewScreen
+ }, {
+ .fromType = MAP_TYPE_ROUTE,
+ .toType = MAP_TYPE_UNDERGROUND,
+ .isEnter = TRUE,
+ .isExit = FALSE,
+ .func1 = FlashTransition_Enter,
+ .func2 = RunMapPreviewScreen
+ }, {
+ .fromType = MAP_TYPE_UNDERWATER,
+ .toType = MAP_TYPE_UNDERGROUND,
+ .isEnter = TRUE,
+ .isExit = FALSE,
+ .func1 = FlashTransition_Enter,
+ .func2 = RunMapPreviewScreen
+ }, {
+ .fromType = MAP_TYPE_OCEAN_ROUTE,
+ .toType = MAP_TYPE_UNDERGROUND,
+ .isEnter = TRUE,
+ .isExit = FALSE,
+ .func1 = FlashTransition_Enter,
+ .func2 = RunMapPreviewScreen
+ }, {
+ .fromType = MAP_TYPE_UNKNOWN,
+ .toType = MAP_TYPE_UNDERGROUND,
+ .isEnter = TRUE,
+ .isExit = FALSE,
+ .func1 = FlashTransition_Enter,
+ .func2 = RunMapPreviewScreen
+ }, {
+ .fromType = MAP_TYPE_INDOOR,
+ .toType = MAP_TYPE_UNDERGROUND,
+ .isEnter = TRUE,
+ .isExit = FALSE,
+ .func1 = FlashTransition_Enter,
+ .func2 = RunMapPreviewScreen
+ }, {
+ .fromType = MAP_TYPE_SECRET_BASE,
+ .toType = MAP_TYPE_UNDERGROUND,
+ .isEnter = TRUE,
+ .isExit = FALSE,
+ .func1 = FlashTransition_Enter,
+ .func2 = RunMapPreviewScreen
+ }, {
+ .fromType = MAP_TYPE_UNDERGROUND,
+ .toType = MAP_TYPE_TOWN,
+ .isEnter = FALSE,
+ .isExit = TRUE,
+ .func1 = FlashTransition_Exit,
+ .func2 = RunMapPreviewScreen
+ }, {
+ .fromType = MAP_TYPE_UNDERGROUND,
+ .toType = MAP_TYPE_CITY,
+ .isEnter = FALSE,
+ .isExit = TRUE,
+ .func1 = FlashTransition_Exit,
+ .func2 = RunMapPreviewScreen
+ }, {
+ .fromType = MAP_TYPE_UNDERGROUND,
+ .toType = MAP_TYPE_ROUTE,
+ .isEnter = FALSE,
+ .isExit = TRUE,
+ .func1 = FlashTransition_Exit,
+ .func2 = RunMapPreviewScreen
+ }, {
+ .fromType = MAP_TYPE_UNDERGROUND,
+ .toType = MAP_TYPE_UNDERWATER,
+ .isEnter = FALSE,
+ .isExit = TRUE,
+ .func1 = FlashTransition_Exit,
+ .func2 = RunMapPreviewScreen
+ }, {
+ .fromType = MAP_TYPE_UNDERGROUND,
+ .toType = MAP_TYPE_OCEAN_ROUTE,
+ .isEnter = FALSE,
+ .isExit = TRUE,
+ .func1 = FlashTransition_Exit,
+ .func2 = RunMapPreviewScreen
+ }, {
+ .fromType = MAP_TYPE_UNDERGROUND,
+ .toType = MAP_TYPE_UNKNOWN,
+ .isEnter = FALSE,
+ .isExit = TRUE,
+ .func1 = FlashTransition_Exit,
+ .func2 = RunMapPreviewScreen
+ }, {
+ .fromType = MAP_TYPE_UNDERGROUND,
+ .toType = MAP_TYPE_INDOOR,
+ .isEnter = FALSE,
+ .isExit = TRUE,
+ .func1 = FlashTransition_Exit,
+ .func2 = RunMapPreviewScreen
+ }, {
+ .fromType = MAP_TYPE_UNDERGROUND,
+ .toType = MAP_TYPE_SECRET_BASE,
+ .isEnter = FALSE,
+ .isExit = TRUE,
+ .func1 = FlashTransition_Exit,
+ .func2 = RunMapPreviewScreen
+ }, {0}
+};
+
+static const u16 sCaveTransitionPalette_White[] = INCBIN_U16("graphics/field_effects/flash_white.gbapal");
+static const u16 sCaveTransitionPalette_Black[] = INCBIN_U16("graphics/field_effects/flash_black.gbapal");
+static const u16 sCaveTransitionPalette_Gradient[] = INCBIN_U16("graphics/field_effects/flash_gradient.gbapal");
+static const u32 sCaveTransitionTilemap[] = INCBIN_U32("graphics/field_effects/flash_effect_map.bin.lz");
+static const u32 sCaveTransitionTiles[] = INCBIN_U32("graphics/field_effects/flash_effect_tiles.4bpp.lz");
+
+bool8 SetUpFieldMove_Flash(void)
+{
+ if (gMapHeader.cave != TRUE)
+ return FALSE;
+
+ if (FlagGet(FLAG_SYS_FLASH_ACTIVE))
+ return FALSE;
+
+ gFieldCallback2 = FieldCallback_PrepareFadeInFromMenu;
+ gPostMenuFieldCallback = FieldCallback_Flash;
+ return TRUE;
+}
+
+static void FieldCallback_Flash(void)
+{
+ u8 taskId = CreateFieldEffectShowMon();
+ gFieldEffectArguments[0] = GetCursorSelectionMonId();
+ gTasks[taskId].data[8] = ((uintptr_t)FldEff_UseFlash) >> 16;
+ gTasks[taskId].data[9] = ((uintptr_t)FldEff_UseFlash);
+}
+
+static void FldEff_UseFlash(void)
+{
+ PlaySE(SE_W115);
+ FlagSet(FLAG_SYS_FLASH_ACTIVE);
+ ScriptContext1_SetupScript(EventScript_FldEffFlash);
+}
+
+// Map transition animatics
+
+static void CB2_ChangeMapMain(void)
+{
+ RunTasks();
+ AnimateSprites();
+ BuildOamBuffer();
+ UpdatePaletteFade();
+}
+
+static void VBC_ChangeMapVBlank(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+}
+
+void CB2_DoChangeMap(void)
+{
+ SetVBlankCallback(NULL);
+
+ SetGpuReg(REG_OFFSET_DISPCNT, 0);
+ SetGpuReg(REG_OFFSET_BG2CNT, 0);
+ SetGpuReg(REG_OFFSET_BG1CNT, 0);
+ SetGpuReg(REG_OFFSET_BG0CNT, 0);
+ SetGpuReg(REG_OFFSET_BG2HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG2VOFS, 0);
+ SetGpuReg(REG_OFFSET_BG1HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG1VOFS, 0);
+ SetGpuReg(REG_OFFSET_BG0HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG0VOFS, 0);
+
+ DmaFill16(3, 0, (void *)VRAM, VRAM_SIZE);
+ DmaFill32(3, 0, (void *)OAM, OAM_SIZE);
+ DmaFill16(3, 0, (void *)(PLTT + 2), PLTT_SIZE - 2);
+ ResetPaletteFade();
+ ResetTasks();
+ ResetSpriteData();
+ EnableInterrupts(INTR_FLAG_VBLANK);
+ SetVBlankCallback(VBC_ChangeMapVBlank);
+ SetMainCallback2(CB2_ChangeMapMain);
+ if (!TryDoMapTransition())
+ SetMainCallback2(gMain.savedCallback);
+}
+
+static bool8 TryDoMapTransition(void)
+{
+ u8 fromType = GetLastUsedWarpMapType();
+ u8 toType = GetCurrentMapType();
+ u8 i = 0;
+ if (GetLastUsedWarpMapSectionId() != gMapHeader.regionMapSectionId && MapHasPreviewScreen_HandleQLState2(gMapHeader.regionMapSectionId, MPS_TYPE_CAVE) == TRUE)
+ {
+ RunMapPreviewScreen(gMapHeader.regionMapSectionId);
+ return TRUE;
+ }
+ for (; sTransitionTypes[i].fromType != 0; i++)
+ {
+ if (sTransitionTypes[i].fromType == fromType && sTransitionTypes[i].toType == toType)
+ {
+ sTransitionTypes[i].func1();
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+bool8 MapTransitionIsEnter(u8 _fromType, u8 _toType)
+{
+ u8 fromType = _fromType;
+ u8 toType = _toType;
+ u8 i = 0;
+ for (; sTransitionTypes[i].fromType != 0; i++)
+ {
+ if (sTransitionTypes[i].fromType == fromType && sTransitionTypes[i].toType == toType)
+ {
+ return sTransitionTypes[i].isEnter;
+ }
+ }
+ return FALSE;
+}
+
+bool8 MapTransitionIsExit(u8 _fromType, u8 _toType)
+{
+ u8 fromType = _fromType;
+ u8 toType = _toType;
+ u8 i = 0;
+ for (; sTransitionTypes[i].fromType != 0; i++)
+ {
+ if (sTransitionTypes[i].fromType == fromType && sTransitionTypes[i].toType == toType)
+ {
+ return sTransitionTypes[i].isExit;
+ }
+ }
+ return FALSE;
+}
+
+static void FlashTransition_Exit(void)
+{
+ CreateTask(Task_FlashTransition_Exit_0, 0);
+}
+
+static void Task_FlashTransition_Exit_0(u8 taskId)
+{
+ gTasks[taskId].func = Task_FlashTransition_Exit_1;
+}
+
+static void Task_FlashTransition_Exit_1(u8 taskId)
+{
+ SetGpuReg(REG_OFFSET_DISPCNT, 0);
+ LZ77UnCompVram(sCaveTransitionTiles, (void *)BG_CHAR_ADDR(3));
+ LZ77UnCompVram(sCaveTransitionTilemap, (void *)BG_SCREEN_ADDR(31));
+ LoadPalette(sCaveTransitionPalette_White, 0xE0, 0x20);
+ LoadPalette(sCaveTransitionPalette_Gradient + 8, 0xE0, 0x10);
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG0 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG1 | BLDCNT_TGT2_BG2 | BLDCNT_TGT2_BG3 | BLDCNT_TGT2_OBJ | BLDCNT_TGT2_BD);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ SetGpuReg(REG_OFFSET_BLDY, 0);
+ SetGpuReg(REG_OFFSET_BG0CNT, BGCNT_PRIORITY(0) | BGCNT_CHARBASE(3) | BGCNT_SCREENBASE(31));
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG0_ON | DISPCNT_OBJ_ON);
+ gTasks[taskId].func = Task_FlashTransition_Exit_2;
+ gTasks[taskId].data[0] = 16;
+ gTasks[taskId].data[1] = 0;
+}
+
+static void Task_FlashTransition_Exit_2(u8 taskId)
+{
+ u16 r4 = gTasks[taskId].data[1];
+ SetGpuReg(REG_OFFSET_BLDALPHA, (16 << 8) + r4);
+ if (r4 <= 16)
+ {
+ gTasks[taskId].data[1]++;
+ }
+ else
+ {
+ gTasks[taskId].data[2] = 0;
+ gTasks[taskId].func = Task_FlashTransition_Exit_3;
+ }
+}
+
+static void Task_FlashTransition_Exit_3(u8 taskId)
+{
+ u16 r4;
+ SetGpuReg(REG_OFFSET_BLDALPHA, (16 << 8) + 16);
+ r4 = gTasks[taskId].data[2];
+ if (r4 < 8)
+ {
+ gTasks[taskId].data[2]++;
+ LoadPalette(sCaveTransitionPalette_Gradient + 8 + r4, 0xE0, 0x10 - 2 * r4);
+ }
+ else
+ {
+ LoadPalette(sCaveTransitionPalette_White, 0x00, 0x20);
+ gTasks[taskId].func = Task_FlashTransition_Exit_4;
+ gTasks[taskId].data[2] = 8;
+ }
+}
+
+static void Task_FlashTransition_Exit_4(u8 taskId)
+{
+ if (gTasks[taskId].data[2] != 0)
+ gTasks[taskId].data[2]--;
+ else
+ SetMainCallback2(gMain.savedCallback);
+}
+
+static void FlashTransition_Enter(void)
+{
+ CreateTask(Task_FlashTransition_Enter_0, 0);
+}
+
+static void Task_FlashTransition_Enter_0(u8 taskId)
+{
+ gTasks[taskId].func = Task_FlashTransition_Enter_1;
+}
+
+static void Task_FlashTransition_Enter_1(u8 taskId)
+{
+ SetGpuReg(REG_OFFSET_DISPCNT, 0);
+ LZ77UnCompVram(sCaveTransitionTiles, (void *)BG_CHAR_ADDR(3));
+ LZ77UnCompVram(sCaveTransitionTilemap, (void *)BG_SCREEN_ADDR(31));
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ SetGpuReg(REG_OFFSET_BLDY, 0);
+ SetGpuReg(REG_OFFSET_BG0CNT, BGCNT_PRIORITY(0) | BGCNT_CHARBASE(3) | BGCNT_SCREENBASE(31));
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG0_ON | DISPCNT_OBJ_ON);
+ LoadPalette(sCaveTransitionPalette_White, 0xE0, 0x20);
+ LoadPalette(sCaveTransitionPalette_Black, 0, 0x20);
+ gTasks[taskId].func = Task_FlashTransition_Enter_2;
+ gTasks[taskId].data[0] = 16;
+ gTasks[taskId].data[1] = 0;
+ gTasks[taskId].data[2] = 0;
+}
+
+static void Task_FlashTransition_Enter_2(u8 taskId)
+{
+ u16 r4;
+ r4 = gTasks[taskId].data[2];
+ if (r4 < 16)
+ {
+ gTasks[taskId].data[2]++;
+ gTasks[taskId].data[2]++;
+ LoadPalette(&sCaveTransitionPalette_Gradient[16 - (r4 + 1)], 0xE0, 2 * (r4 + 1));
+ }
+ else
+ {
+ SetGpuReg(REG_OFFSET_BLDALPHA, (16 << 8) + 16);
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG0 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG1 | BLDCNT_TGT2_BG2 | BLDCNT_TGT2_BG3 | BLDCNT_TGT2_OBJ | BLDCNT_TGT2_BD);
+ gTasks[taskId].func = Task_FlashTransition_Enter_3;
+ }
+}
+
+static void Task_FlashTransition_Enter_3(u8 taskId)
+{
+ u16 r4 = 16 - gTasks[taskId].data[1];
+ SetGpuReg(REG_OFFSET_BLDALPHA, (16 << 8) + r4);
+ if (r4 != 0)
+ {
+ gTasks[taskId].data[1]++;
+ }
+ else
+ {
+ LoadPalette(sCaveTransitionPalette_Black, 0x00, 0x20);
+ SetMainCallback2(gMain.savedCallback);
+ }
+}
+
+static void RunMapPreviewScreen(u8 mapSecId)
+{
+ u8 taskId = CreateTask(Task_MapPreviewScreen_0, 0);
+ gTasks[taskId].data[3] = mapSecId;
+}
+
+static void Task_MapPreviewScreen_0(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+ switch (data[0])
+ {
+ case 0:
+ SetWordTaskArg(taskId, 5, (uintptr_t)gMain.vblankCallback);
+ SetVBlankCallback(NULL);
+ MapPreview_InitBgs();
+ MapPreview_LoadGfx(data[3]);
+ BlendPalettes(0xFFFFFFFF, 0x10, RGB_BLACK);
+ data[0]++;
+ break;
+ case 1:
+ if (!MapPreview_IsGfxLoadFinished())
+ {
+ data[4] = MapPreview_CreateMapNameWindow(data[3]);
+ CopyWindowToVram(data[4], 3);
+ data[0]++;
+ }
+ break;
+ case 2:
+ if (!IsDma3ManagerBusyWithBgCopy())
+ {
+ BeginNormalPaletteFade(0xFFFFFFFF, -1, 16, 0, RGB_BLACK);
+ SetVBlankCallback((IntrCallback)GetWordTaskArg(taskId, 5));
+ data[0]++;
+ }
+ break;
+ case 3:
+ if (!UpdatePaletteFade())
+ {
+ data[2] = MapPreview_GetDuration(data[3]);
+ data[0]++;
+ }
+ break;
+ case 4:
+ data[1]++;
+ if (data[1] > data[2] || JOY_HELD(B_BUTTON))
+ {
+ BeginNormalPaletteFade(0xFFFFFFFF, -2, 0, 16, RGB_WHITE);
+ data[0]++;
+ }
+ break;
+ case 5:
+ if (!UpdatePaletteFade())
+ {
+ int i;
+ for (i = 0; i < 16; i++)
+ {
+ data[i] = 0;
+ }
+ MapPreview_Unload(data[4]);
+ gTasks[taskId].func = Task_FlashTransition_Enter_1;
+ }
+ break;
+ }
+}