pokeemerald/src/fldeff_flash.c

370 lines
11 KiB
C
Raw Normal View History

2018-02-26 13:24:54 +01:00
#include "global.h"
2018-02-27 06:03:23 +01:00
#include "braille_puzzles.h"
2018-02-26 13:24:54 +01:00
#include "event_data.h"
#include "event_scripts.h"
#include "field_effect.h"
2018-12-24 21:59:05 +01:00
#include "fldeff.h"
2018-02-26 13:24:54 +01:00
#include "gpu_regs.h"
#include "main.h"
2018-11-14 01:01:50 +01:00
#include "overworld.h"
2018-02-26 13:24:54 +01:00
#include "palette.h"
#include "party_menu.h"
#include "script.h"
#include "sound.h"
#include "sprite.h"
#include "task.h"
2018-11-14 01:01:50 +01:00
#include "constants/songs.h"
2019-09-10 19:40:28 +02:00
#include "constants/map_types.h"
2018-02-26 13:24:54 +01:00
// structures
struct FlashStruct
{
2019-09-10 19:40:28 +02:00
u8 fromType;
u8 toType;
2019-09-29 22:33:13 +02:00
bool8 isEnter;
bool8 isExit;
2018-02-26 13:24:54 +01:00
void (*func)(void);
};
// static functions
2019-10-22 23:28:05 +02:00
static void FieldCallback_Flash(void);
static void FldEff_UseFlash(void);
2019-09-29 22:33:13 +02:00
static bool8 TryDoMapTransition(void);
2019-09-10 19:40:28 +02:00
static void DoExitCaveTransition(void);
static void Task_ExitCaveTransition1(u8 taskId);
static void Task_ExitCaveTransition2(u8 taskId);
static void Task_ExitCaveTransition3(u8 taskId);
static void Task_ExitCaveTransition4(u8 taskId);
static void Task_ExitCaveTransition5(u8 taskId);
static void DoEnterCaveTransition(void);
static void Task_EnterCaveTransition1(u8 taskId);
static void Task_EnterCaveTransition2(u8 taskId);
static void Task_EnterCaveTransition3(u8 taskId);
static void Task_EnterCaveTransition4(u8 taskId);
2018-02-26 13:24:54 +01:00
// rodata
2019-09-10 19:40:28 +02:00
static const struct FlashStruct sTransitionTypes[] =
2018-02-27 06:03:23 +01:00
{
2019-09-29 22:33:13 +02:00
{MAP_TYPE_TOWN, MAP_TYPE_UNDERGROUND, TRUE, FALSE, DoEnterCaveTransition},
{MAP_TYPE_CITY, MAP_TYPE_UNDERGROUND, TRUE, FALSE, DoEnterCaveTransition},
{MAP_TYPE_ROUTE, MAP_TYPE_UNDERGROUND, TRUE, FALSE, DoEnterCaveTransition},
{MAP_TYPE_UNDERWATER, MAP_TYPE_UNDERGROUND, TRUE, FALSE, DoEnterCaveTransition},
{MAP_TYPE_OCEAN_ROUTE, MAP_TYPE_UNDERGROUND, TRUE, FALSE, DoEnterCaveTransition},
2020-03-31 21:37:31 +02:00
{MAP_TYPE_UNKNOWN, MAP_TYPE_UNDERGROUND, TRUE, FALSE, DoEnterCaveTransition},
2019-09-29 22:33:13 +02:00
{MAP_TYPE_INDOOR, MAP_TYPE_UNDERGROUND, TRUE, FALSE, DoEnterCaveTransition},
{MAP_TYPE_SECRET_BASE, MAP_TYPE_UNDERGROUND, TRUE, FALSE, DoEnterCaveTransition},
{MAP_TYPE_UNDERGROUND, MAP_TYPE_TOWN, FALSE, TRUE, DoExitCaveTransition},
{MAP_TYPE_UNDERGROUND, MAP_TYPE_CITY, FALSE, TRUE, DoExitCaveTransition},
{MAP_TYPE_UNDERGROUND, MAP_TYPE_ROUTE, FALSE, TRUE, DoExitCaveTransition},
{MAP_TYPE_UNDERGROUND, MAP_TYPE_UNDERWATER, FALSE, TRUE, DoExitCaveTransition},
{MAP_TYPE_UNDERGROUND, MAP_TYPE_OCEAN_ROUTE, FALSE, TRUE, DoExitCaveTransition},
2020-03-31 21:37:31 +02:00
{MAP_TYPE_UNDERGROUND, MAP_TYPE_UNKNOWN, FALSE, TRUE, DoExitCaveTransition},
2019-09-29 22:33:13 +02:00
{MAP_TYPE_UNDERGROUND, MAP_TYPE_INDOOR, FALSE, TRUE, DoExitCaveTransition},
{MAP_TYPE_UNDERGROUND, MAP_TYPE_SECRET_BASE, FALSE, TRUE, DoExitCaveTransition},
{},
2018-02-27 06:03:23 +01:00
};
2018-02-26 13:24:54 +01:00
2018-02-27 06:03:23 +01:00
static const u16 gCaveTransitionPalette_White[] = INCBIN_U16("graphics/misc/cave_transition_white.gbapal");
static const u16 gCaveTransitionPalette_Black[] = INCBIN_U16("graphics/misc/cave_transition_black.gbapal");
2018-02-26 13:24:54 +01:00
2018-02-27 06:03:23 +01:00
static const u16 gUnknown_085B2890[] = INCBIN_U16("graphics/misc/85B2890.gbapal");
static const u16 gUnknown_085B28A0[] = INCBIN_U16("graphics/misc/85B28A0.gbapal");
2018-10-21 09:24:57 +02:00
static const u32 gCaveTransitionTilemap[] = INCBIN_U32("graphics/misc/cave_transition_map.bin.lz");
static const u32 gCaveTransitionTiles[] = INCBIN_U32("graphics/misc/cave_transition.4bpp.lz");
2018-02-26 13:24:54 +01:00
// text
bool8 SetUpFieldMove_Flash(void)
{
// In Ruby and Sapphire, Registeel's tomb is opened by using Fly. In Emerald,
// Flash is used instead.
if (ShouldDoBrailleRegisteelEffect())
2018-02-26 13:24:54 +01:00
{
gSpecialVar_Result = GetCursorSelectionMonId();
2018-06-16 00:45:48 +02:00
gFieldCallback2 = FieldCallback_PrepareFadeInFromMenu;
gPostMenuFieldCallback = SetUpPuzzleEffectRegisteel;
2018-02-26 13:24:54 +01:00
return TRUE;
}
else if (gMapHeader.cave == TRUE && !FlagGet(FLAG_SYS_USE_FLASH))
{
2018-06-16 00:45:48 +02:00
gFieldCallback2 = FieldCallback_PrepareFadeInFromMenu;
2019-10-22 23:28:05 +02:00
gPostMenuFieldCallback = FieldCallback_Flash;
2018-02-26 13:24:54 +01:00
return TRUE;
}
return FALSE;
}
2019-10-22 23:28:05 +02:00
static void FieldCallback_Flash(void)
2018-02-26 13:24:54 +01:00
{
u8 taskId = CreateFieldMoveTask();
2018-02-26 13:24:54 +01:00
gFieldEffectArguments[0] = GetCursorSelectionMonId();
2019-10-22 23:28:05 +02:00
gTasks[taskId].data[8] = (uintptr_t)FldEff_UseFlash >> 16;
gTasks[taskId].data[9] = (uintptr_t)FldEff_UseFlash;
2018-02-26 13:24:54 +01:00
}
2019-10-22 23:28:05 +02:00
static void FldEff_UseFlash(void)
2018-02-26 13:24:54 +01:00
{
PlaySE(SE_W115);
FlagSet(FLAG_SYS_USE_FLASH);
2020-07-02 10:59:52 +02:00
ScriptContext1_SetupScript(EventScript_UseFlash);
2018-02-26 13:24:54 +01:00
}
2019-09-10 19:40:28 +02:00
static void CB2_ChangeMapMain(void)
2018-02-26 13:24:54 +01:00
{
RunTasks();
AnimateSprites();
BuildOamBuffer();
UpdatePaletteFade();
}
2019-09-10 19:40:28 +02:00
static void VBC_ChangeMapVBlank(void)
2018-02-26 13:24:54 +01:00
{
LoadOam();
ProcessSpriteCopyRequests();
TransferPlttBuffer();
}
2019-09-10 19:40:28 +02:00
void CB2_DoChangeMap(void)
2018-02-26 13:24:54 +01:00
{
u16 ime;
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();
ime = REG_IME;
REG_IME = 0;
REG_IE |= INTR_FLAG_VBLANK;
REG_IME = ime;
2019-09-10 19:40:28 +02:00
SetVBlankCallback(VBC_ChangeMapVBlank);
SetMainCallback2(CB2_ChangeMapMain);
2019-09-29 22:33:13 +02:00
if (!TryDoMapTransition())
2018-02-26 13:24:54 +01:00
SetMainCallback2(gMain.savedCallback);
}
2019-09-29 22:33:13 +02:00
static bool8 TryDoMapTransition(void)
2018-02-26 13:24:54 +01:00
{
u8 i;
2019-09-10 19:40:28 +02:00
u8 fromType = GetLastUsedWarpMapType();
u8 toType = GetCurrentMapType();
2018-02-26 13:24:54 +01:00
2019-09-10 19:40:28 +02:00
for (i = 0; sTransitionTypes[i].fromType; i++)
2018-02-26 13:24:54 +01:00
{
2019-09-10 19:40:28 +02:00
if (sTransitionTypes[i].fromType == fromType && sTransitionTypes[i].toType == toType)
2018-02-26 13:24:54 +01:00
{
2019-09-10 19:40:28 +02:00
sTransitionTypes[i].func();
2018-02-26 13:24:54 +01:00
return TRUE;
}
}
return FALSE;
}
2019-09-10 19:40:28 +02:00
bool8 GetMapPairFadeToType(u8 _fromType, u8 _toType)
2018-02-26 13:24:54 +01:00
{
u8 i;
2019-09-10 19:40:28 +02:00
u8 fromType = _fromType;
u8 toType = _toType;
2018-02-26 13:24:54 +01:00
2019-09-10 19:40:28 +02:00
for (i = 0; sTransitionTypes[i].fromType; i++)
2018-02-26 13:24:54 +01:00
{
2019-09-10 19:40:28 +02:00
if (sTransitionTypes[i].fromType == fromType && sTransitionTypes[i].toType == toType)
2018-02-26 13:24:54 +01:00
{
2019-09-29 22:33:13 +02:00
return sTransitionTypes[i].isEnter;
2018-02-26 13:24:54 +01:00
}
}
return FALSE;
}
2019-09-10 19:40:28 +02:00
bool8 GetMapPairFadeFromType(u8 _fromType, u8 _toType)
2018-02-26 13:24:54 +01:00
{
u8 i;
2019-09-10 19:40:28 +02:00
u8 fromType = _fromType;
u8 toType = _toType;
2018-02-26 13:24:54 +01:00
2019-09-10 19:40:28 +02:00
for (i = 0; sTransitionTypes[i].fromType; i++)
2018-02-26 13:24:54 +01:00
{
2019-09-10 19:40:28 +02:00
if (sTransitionTypes[i].fromType == fromType && sTransitionTypes[i].toType == toType)
2018-02-26 13:24:54 +01:00
{
2019-09-29 22:33:13 +02:00
return sTransitionTypes[i].isExit;
2018-02-26 13:24:54 +01:00
}
}
return FALSE;
}
2019-09-10 19:40:28 +02:00
static void DoExitCaveTransition(void)
2018-02-26 13:24:54 +01:00
{
2019-09-10 19:40:28 +02:00
CreateTask(Task_ExitCaveTransition1, 0);
2018-02-26 13:24:54 +01:00
}
2019-09-10 19:40:28 +02:00
static void Task_ExitCaveTransition1(u8 taskId)
2018-02-26 13:24:54 +01:00
{
2019-09-10 19:40:28 +02:00
gTasks[taskId].func = Task_ExitCaveTransition2;
2018-02-26 13:24:54 +01:00
}
2019-09-10 19:40:28 +02:00
static void Task_ExitCaveTransition2(u8 taskId)
2018-02-26 13:24:54 +01:00
{
SetGpuReg(REG_OFFSET_DISPCNT, 0);
2019-07-29 04:18:28 +02:00
LZ77UnCompVram(gCaveTransitionTiles, (void *)(VRAM + 0xC000));
LZ77UnCompVram(gCaveTransitionTilemap, (void *)(VRAM + 0xF800));
2018-02-26 13:24:54 +01:00
LoadPalette(gCaveTransitionPalette_White, 0xE0, 0x20);
LoadPalette(gUnknown_085B28A0, 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)
| BGCNT_16COLOR
| BGCNT_TXT256x256);
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0
| DISPCNT_OBJ_1D_MAP
| DISPCNT_BG0_ON
| DISPCNT_OBJ_ON);
2019-09-10 19:40:28 +02:00
gTasks[taskId].func = Task_ExitCaveTransition3;
2018-02-26 13:24:54 +01:00
gTasks[taskId].data[0] = 16;
gTasks[taskId].data[1] = 0;
}
2019-09-10 19:40:28 +02:00
static void Task_ExitCaveTransition3(u8 taskId)
2018-02-26 13:24:54 +01:00
{
u16 count = gTasks[taskId].data[1];
u16 blend = count + 0x1000;
SetGpuReg(REG_OFFSET_BLDALPHA, blend);
if (count <= 0x10)
{
gTasks[taskId].data[1]++;
}
else
{
gTasks[taskId].data[2] = 0;
2019-09-10 19:40:28 +02:00
gTasks[taskId].func = Task_ExitCaveTransition4;
2018-02-26 13:24:54 +01:00
}
}
2019-09-10 19:40:28 +02:00
static void Task_ExitCaveTransition4(u8 taskId)
2018-02-26 13:24:54 +01:00
{
u16 count;
2018-02-27 06:03:23 +01:00
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16, 16));
2018-02-26 13:24:54 +01:00
count = gTasks[taskId].data[2];
if (count < 8)
{
gTasks[taskId].data[2]++;
LoadPalette(&gUnknown_085B28A0[count], 0xE0, 16 - 2 * count);
}
else
{
LoadPalette(gCaveTransitionPalette_White, 0, 0x20);
2019-09-10 19:40:28 +02:00
gTasks[taskId].func = Task_ExitCaveTransition5;
2018-02-26 13:24:54 +01:00
gTasks[taskId].data[2] = 8;
}
}
2019-09-10 19:40:28 +02:00
static void Task_ExitCaveTransition5(u8 taskId)
2018-02-26 13:24:54 +01:00
{
if (gTasks[taskId].data[2])
gTasks[taskId].data[2]--;
else
SetMainCallback2(gMain.savedCallback);
}
2019-09-10 19:40:28 +02:00
static void DoEnterCaveTransition(void)
2018-02-26 13:24:54 +01:00
{
2019-09-10 19:40:28 +02:00
CreateTask(Task_EnterCaveTransition1, 0);
2018-02-26 13:24:54 +01:00
}
2019-09-10 19:40:28 +02:00
static void Task_EnterCaveTransition1(u8 taskId)
2018-02-26 13:24:54 +01:00
{
2019-09-10 19:40:28 +02:00
gTasks[taskId].func = Task_EnterCaveTransition2;
2018-02-26 13:24:54 +01:00
}
2019-09-10 19:40:28 +02:00
static void Task_EnterCaveTransition2(u8 taskId)
2018-02-26 13:24:54 +01:00
{
SetGpuReg(REG_OFFSET_DISPCNT, 0);
2019-07-29 04:18:28 +02:00
LZ77UnCompVram(gCaveTransitionTiles, (void *)(VRAM + 0xC000));
LZ77UnCompVram(gCaveTransitionTilemap, (void *)(VRAM + 0xF800));
2018-02-26 13:24:54 +01:00
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)
| BGCNT_16COLOR
| BGCNT_TXT256x256);
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0
| DISPCNT_OBJ_1D_MAP
| DISPCNT_BG0_ON
| DISPCNT_OBJ_ON);
LoadPalette(gCaveTransitionPalette_White, 0xE0, 0x20);
LoadPalette(gCaveTransitionPalette_Black, 0, 0x20);
2019-09-10 19:40:28 +02:00
gTasks[taskId].func = Task_EnterCaveTransition3;
2018-02-26 13:24:54 +01:00
gTasks[taskId].data[0] = 16;
gTasks[taskId].data[1] = 0;
gTasks[taskId].data[2] = 0;
}
2019-09-10 19:40:28 +02:00
static void Task_EnterCaveTransition3(u8 taskId)
2018-02-26 13:24:54 +01:00
{
u16 count = gTasks[taskId].data[2];
if (count < 16)
{
gTasks[taskId].data[2]++;
gTasks[taskId].data[2]++;
LoadPalette(&gUnknown_085B2890[15 - count], 0xE0, 2 * (count + 1));
}
else
{
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16, 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);
2019-09-10 19:40:28 +02:00
gTasks[taskId].func = Task_EnterCaveTransition4;
2018-02-26 13:24:54 +01:00
}
}
2019-09-10 19:40:28 +02:00
static void Task_EnterCaveTransition4(u8 taskId)
2018-02-26 13:24:54 +01:00
{
u16 count = 16 - gTasks[taskId].data[1];
u16 blend = count + 0x1000;
SetGpuReg(REG_OFFSET_BLDALPHA, blend);
if (count)
{
gTasks[taskId].data[1]++;
}
else
{
LoadPalette(gCaveTransitionPalette_Black, 0, 0x20);
SetMainCallback2(gMain.savedCallback);
}
}