summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPikalaxALT <pikalaxalt@gmail.com>2020-01-06 13:59:20 -0500
committerPikalaxALT <pikalaxalt@gmail.com>2020-01-06 13:59:20 -0500
commitccb5c0f324e2b9002a687c9111b2675bc6bd101d (patch)
tree84d587d63154d9a8da3e9983aae2042f09767737 /src
parent498ad1e6af6b219aa54b827e59325b6fbcb54343 (diff)
parent26f7ba482384ad4f63063797a527b7fb33572aa1 (diff)
Merge branch 'master' of github.com:pret/pokefirered into region_map
Diffstat (limited to 'src')
-rw-r--r--src/field_fadetransition.c14
-rw-r--r--src/field_screen_effect.c265
-rw-r--r--src/field_tasks.c293
-rw-r--r--src/scrcmd.c2
-rw-r--r--src/seagallop.c2
5 files changed, 566 insertions, 10 deletions
diff --git a/src/field_fadetransition.c b/src/field_fadetransition.c
index 6627aaf48..e2da82de2 100644
--- a/src/field_fadetransition.c
+++ b/src/field_fadetransition.c
@@ -330,7 +330,7 @@ static void sub_807DFBC(u8 taskId)
case 5:
sub_807DCB0(0);
FreezeObjectEvents();
- sub_807F114();
+ DoOutwardBarnDoorWipe();
sub_807DBAC();
task->data[0] = 6;
break;
@@ -362,7 +362,7 @@ static void sub_807DFBC(u8 taskId)
}
break;
case 9:
- if (sub_807E418() && walkrun_is_standing_still() && !FieldIsDoorAnimationRunning() && !FuncIsActiveTask(sub_807F204))
+ if (sub_807E418() && walkrun_is_standing_still() && !FieldIsDoorAnimationRunning() && !FuncIsActiveTask(Task_BarnDoorWipe))
{
ObjectEventClearHeldMovementIfFinished(&gObjectEvents[GetObjectEventIdByLocalIdAndMap(0xFF, 0, 0)]);
task->data[0] = 4;
@@ -627,7 +627,7 @@ static void sub_807E5EC(u8 taskId)
task->data[0]++;
break;
case 1:
- if (!sub_807E40C() && sub_8055FC4())
+ if (!sub_807E40C() && BGMusicStopped())
task->data[0]++;
break;
case 2:
@@ -660,7 +660,7 @@ static void sub_807E678(u8 taskId)
data[0]++;
break;
case 1:
- if (!sub_807E40C() && sub_8055FC4())
+ if (!sub_807E40C() && BGMusicStopped())
{
sub_800AAC0();
data[0]++;
@@ -693,7 +693,7 @@ static void sub_807E718(u8 taskId)
task->data[0]++;
break;
case 1:
- if (!sub_807E40C() && sub_8055FC4())
+ if (!sub_807E40C() && BGMusicStopped())
task->data[0]++;
break;
case 2:
@@ -724,7 +724,7 @@ static void sub_807E784(u8 taskId)
}
break;
case 2:
- if (!sub_807E40C() && sub_8055FC4())
+ if (!sub_807E40C() && BGMusicStopped())
task->data[0]++;
break;
case 3:
@@ -828,7 +828,7 @@ static void sub_807E980(u8 taskId)
break;
case 3:
sub_807EAC4(data[2], data[3], &data[4], &data[5], &data[6]);
- if (!sub_807E40C() && sub_8055FC4())
+ if (!sub_807E40C() && BGMusicStopped())
data[0]++;
break;
default:
diff --git a/src/field_screen_effect.c b/src/field_screen_effect.c
index 19ed25950..a552c47a2 100644
--- a/src/field_screen_effect.c
+++ b/src/field_screen_effect.c
@@ -1,6 +1,19 @@
#include "global.h"
+#include "field_screen_effect.h"
+#include "gpu_regs.h"
+#include "overworld.h"
+#include "scanline_effect.h"
+#include "script.h"
+#include "task.h"
-void SetFlashScanlineEffectWindowBoundary(u16 *dest, u32 y, s32 left, s32 right)
+static const u16 sFlashLevelPixelRadii[] = {
+ 0x00c8, 0x0048, 0x0038, 0x0028, 0x0018, 0x0000
+};
+
+static void Task_EnableScriptAfterMusicFade(u8 taskId);
+static void Task_BarnDoorWipeChild(u8 taskId);
+
+static void SetFlashScanlineEffectWindowBoundary(u16 *dest, u32 y, s32 left, s32 right)
{
if (y <= 160)
{
@@ -73,3 +86,253 @@ void SetFlashScanlineEffectWindowBoundaries(u16 *dest, s32 centerX, s32 centerY,
}
}
}
+
+#define tState data[0]
+#define tFlashCenterX data[1]
+#define tFlashCenterY data[2]
+#define tCurFlashRadius data[3]
+#define tDestFlashRadius data[4]
+#define tFlashRadiusDelta data[5]
+#define tClearScanlineEffect data[6]
+
+static void UpdateFlashLevelEffect(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ switch (tState)
+ {
+ case 0:
+ SetFlashScanlineEffectWindowBoundaries(gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer], tFlashCenterX, tFlashCenterY, tCurFlashRadius);
+ tState = 1;
+ break;
+ case 1:
+ SetFlashScanlineEffectWindowBoundaries(gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer], tFlashCenterX, tFlashCenterY, tCurFlashRadius);
+ tState = 0;
+ tCurFlashRadius += tFlashRadiusDelta;
+ if (tCurFlashRadius > tDestFlashRadius)
+ {
+ if (tClearScanlineEffect == TRUE)
+ {
+ ScanlineEffect_Stop();
+ tState = 2;
+ }
+ else
+ {
+ DestroyTask(taskId);
+ }
+ }
+ break;
+ case 2:
+ ScanlineEffect_Clear();
+ DestroyTask(taskId);
+ break;
+ }
+}
+
+static void sub_807EF7C(u8 taskId)
+{
+ if (!FuncIsActiveTask(UpdateFlashLevelEffect))
+ {
+ EnableBothScriptContexts();
+ DestroyTask(taskId);
+ }
+}
+
+static void sub_807EFA4(void)
+{
+ if (!FuncIsActiveTask(sub_807EF7C))
+ CreateTask(sub_807EF7C, 80);
+}
+
+static u8 sub_807EFC8(s32 centerX, s32 centerY, s32 initialFlashRadius, s32 destFlashRadius, bool32 clearScanlineEffect, u8 delta)
+{
+ 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;
+}
+
+#undef tState
+#undef tCurFlashRadius
+#undef tDestFlashRadius
+#undef tFlashRadiusDelta
+#undef tClearScanlineEffect
+
+void AnimateFlash(u8 flashLevel)
+{
+ u8 curFlashLevel = Overworld_GetFlashLevel();
+ bool32 value = FALSE;
+ if (!flashLevel)
+ value = TRUE;
+ sub_807EFC8(120, 80, sFlashLevelPixelRadii[curFlashLevel], sFlashLevelPixelRadii[flashLevel], value, 2);
+ sub_807EFA4();
+ ScriptContext2_Enable();
+}
+
+void WriteFlashScanlineEffectBuffer(u8 flashLevel)
+{
+ if (flashLevel)
+ {
+ SetFlashScanlineEffectWindowBoundaries(&gScanlineEffectRegBuffers[0][0], 120, 80, sFlashLevelPixelRadii[flashLevel]);
+ CpuFastCopy(&gScanlineEffectRegBuffers[0], &gScanlineEffectRegBuffers[1], 240 * 8);
+ }
+}
+
+void sub_807F0B0(void)
+{
+ Overworld_FadeOutMapMusic();
+ CreateTask(Task_EnableScriptAfterMusicFade, 80);
+}
+
+static void Task_EnableScriptAfterMusicFade(u8 taskId)
+{
+ if (BGMusicStopped() == TRUE)
+ {
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+ }
+}
+
+#define tState data[9]
+#define tDirection data[10]
+#define DIR_WIPE_IN 0 // From edges to center.
+#define DIR_WIPE_OUT 1 // From center to edges.
+#define tChildOffset data[0]
+
+static void DoInwardBarnDoorFade(void)
+{
+ u8 taskId = CreateTask(Task_BarnDoorWipe, 80);
+ gTasks[taskId].tDirection = DIR_WIPE_IN;
+}
+
+void DoOutwardBarnDoorWipe(void)
+{
+ u8 taskId = CreateTask(Task_BarnDoorWipe, 80);
+ gTasks[taskId].tDirection = DIR_WIPE_OUT;
+}
+
+static void BarnDoorWipeSaveGpuRegs(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+ data[0] = GetGpuReg(REG_OFFSET_DISPCNT);
+ data[1] = GetGpuReg(REG_OFFSET_WININ);
+ data[2] = GetGpuReg(REG_OFFSET_WINOUT);
+ data[3] = GetGpuReg(REG_OFFSET_BLDCNT);
+ data[4] = GetGpuReg(REG_OFFSET_BLDALPHA);
+ data[5] = GetGpuReg(REG_OFFSET_WIN0H);
+ data[6] = GetGpuReg(REG_OFFSET_WIN0V);
+ data[7] = GetGpuReg(REG_OFFSET_WIN1H);
+ data[8] = GetGpuReg(REG_OFFSET_WIN1V);
+}
+
+static void BarnDoorWipeLoadGpuRegs(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+ SetGpuReg(REG_OFFSET_DISPCNT, data[0]);
+ SetGpuReg(REG_OFFSET_WININ, data[1]);
+ SetGpuReg(REG_OFFSET_WINOUT, data[2]);
+ SetGpuReg(REG_OFFSET_BLDCNT, data[3]);
+ SetGpuReg(REG_OFFSET_BLDALPHA, data[4]);
+ SetGpuReg(REG_OFFSET_WIN0H, data[5]);
+ SetGpuReg(REG_OFFSET_WIN0V, data[6]);
+ SetGpuReg(REG_OFFSET_WIN1H, data[7]);
+ SetGpuReg(REG_OFFSET_WIN1V, data[8]);
+}
+
+void Task_BarnDoorWipe(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+ switch (tState)
+ {
+ case 0:
+ BarnDoorWipeSaveGpuRegs(taskId);
+ SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON);
+ SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN1_ON);
+ if (data[10] == 0)
+ {
+ SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE(0, 0));
+ SetGpuReg(REG_OFFSET_WIN1H, WIN_RANGE(240, 255));
+ SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE(0, 255));
+ SetGpuReg(REG_OFFSET_WIN1V, WIN_RANGE(0, 255));
+ }
+ else
+ {
+ SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE(0, 120));
+ SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE(0, 255));
+ SetGpuReg(REG_OFFSET_WIN1H, WIN_RANGE(120, 255));
+ SetGpuReg(REG_OFFSET_WIN1V, WIN_RANGE(0, 255));
+ }
+ SetGpuReg(REG_OFFSET_WININ, 0);
+ SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR);
+ tState = 1;
+ break;
+ case 1:
+ CreateTask(Task_BarnDoorWipeChild, 80);
+ tState = 2;
+ break;
+ case 2:
+ if (!FuncIsActiveTask(Task_BarnDoorWipeChild))
+ {
+ tState = 3;
+ }
+ break;
+ case 3:
+ BarnDoorWipeLoadGpuRegs(taskId);
+ DestroyTask(taskId);
+ break;
+ }
+}
+
+static void Task_BarnDoorWipeChild(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+ u8 parentTaskId = FindTaskIdByFunc(Task_BarnDoorWipe);
+ s16 lhs, rhs;
+ if (gTasks[parentTaskId].tDirection == DIR_WIPE_IN)
+ {
+ lhs = tChildOffset;
+ rhs = 240 - tChildOffset;
+ if (lhs > 120)
+ {
+ DestroyTask(taskId);
+ return;
+ }
+ }
+ else
+ {
+ lhs = 120 - tChildOffset;
+ rhs = 120 + tChildOffset;
+ if (lhs < 0)
+ {
+ DestroyTask(taskId);
+ return;
+ }
+ }
+ SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE(0, lhs));
+ SetGpuReg(REG_OFFSET_WIN1H, WIN_RANGE(rhs, 240));
+ if (lhs <= 89)
+ {
+ tChildOffset += 4;
+ }
+ else
+ {
+ tChildOffset += 2;
+ }
+}
+
+#undef tState
+#undef tDirection
+#undef DIR_WIPE_IN
+#undef DIR_WIPE_OUT
+#undef tChildOffset
diff --git a/src/field_tasks.c b/src/field_tasks.c
new file mode 100644
index 000000000..7ca6d0e7b
--- /dev/null
+++ b/src/field_tasks.c
@@ -0,0 +1,293 @@
+#include "global.h"
+#include "bike.h"
+#include "event_data.h"
+#include "field_camera.h"
+#include "field_effect_helpers.h"
+#include "field_player_avatar.h"
+#include "fieldmap.h"
+#include "metatile_behavior.h"
+#include "overworld.h"
+#include "quest_log.h"
+#include "script.h"
+#include "sound.h"
+#include "task.h"
+#include "constants/flags.h"
+#include "constants/songs.h"
+#include "constants/vars.h"
+
+static void DummyPerStepCallback(u8 taskId);
+static void AshGrassPerStepCallback(u8 taskId);
+static void IcefallCaveIcePerStepCallback(u8 taskId);
+static void CrackedFloorPerStepCallback(u8 taskId);
+
+static const TaskFunc sPerStepCallbacks[] =
+{
+ DummyPerStepCallback,
+ AshGrassPerStepCallback,
+ DummyPerStepCallback,
+ DummyPerStepCallback,
+ IcefallCaveIcePerStepCallback,
+ DummyPerStepCallback,
+ DummyPerStepCallback,
+ CrackedFloorPerStepCallback
+};
+
+static const u8 sIcefallCaveIceTileCoords[][2] =
+{
+ { 0x08, 0x03 },
+ { 0x0a, 0x05 },
+ { 0x0f, 0x05 },
+ { 0x08, 0x09 },
+ { 0x09, 0x09 },
+ { 0x10, 0x09 },
+ { 0x08, 0x0a },
+ { 0x09, 0x0a },
+ { 0x08, 0x0e }
+};
+
+static void Task_RunPerStepCallback(u8 taskId)
+{
+ int idx = gTasks[taskId].data[0];
+ sPerStepCallbacks[idx](taskId);
+}
+
+static void Task_RunTimeBasedEvents(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ if (!ScriptContext2_IsEnabled())
+ {
+ if (gUnknown_203ADFA != 2 && gUnknown_203ADFA != 3)
+ {
+ sub_8056078(&data[1], &data[2]);
+ }
+ }
+}
+
+void SetUpFieldTasks(void)
+{
+ if (!FuncIsActiveTask(Task_RunPerStepCallback))
+ {
+ u8 taskId = CreateTask(Task_RunPerStepCallback, 0x50);
+ gTasks[taskId].data[0] = 0;
+ }
+
+ if (!FuncIsActiveTask(Task_RunTimeBasedEvents))
+ CreateTask(Task_RunTimeBasedEvents, 0x50);
+}
+
+void ActivatePerStepCallback(u8 callbackId)
+{
+ u8 taskId = FindTaskIdByFunc(Task_RunPerStepCallback);
+ if (taskId != 0xff)
+ {
+ s32 i;
+ s16 *data = gTasks[taskId].data;
+
+ for (i = 0; i < 16; i++)
+ data[i] = 0;
+
+ if (callbackId >= NELEMS(sPerStepCallbacks))
+ {
+ data[0] = 0;
+ }
+ else
+ {
+ data[0] = callbackId;
+ }
+ }
+}
+
+void ResetFieldTasksArgs(void)
+{
+ u8 taskId;
+ s16 *data;
+
+ taskId = FindTaskIdByFunc(Task_RunPerStepCallback);
+ if (taskId != 0xff)
+ {
+ data = gTasks[taskId].data;
+ }
+ taskId = FindTaskIdByFunc(Task_RunTimeBasedEvents);
+ if (taskId != 0xff)
+ {
+ data = gTasks[taskId].data;
+ data[1] = 0;
+ data[2] = 0;
+ }
+}
+
+static void DummyPerStepCallback(u8 taskId)
+{
+}
+
+static void MarkIcefallCaveCoordVisited(s16 x, s16 y)
+{
+ u8 i = 0;
+ for (; i < NELEMS(sIcefallCaveIceTileCoords); ++i)
+ {
+ if (sIcefallCaveIceTileCoords[i][0] + 7 == x && sIcefallCaveIceTileCoords[i][1] + 7 == y)
+ {
+ FlagSet(i + 1);
+ break;
+ }
+ }
+}
+
+void Special_SetIcefallCaveCrackedIceMetatiles(void)
+{
+ u8 i = 0;
+ for (; i < NELEMS(sIcefallCaveIceTileCoords); ++i)
+ {
+ if (FlagGet(i + 1) == TRUE)
+ {
+ int x = sIcefallCaveIceTileCoords[i][0] + 7;
+ int y = sIcefallCaveIceTileCoords[i][1] + 7;
+ MapGridSetMetatileIdAt(x, y, 0x35a);
+ }
+ }
+}
+
+static void IcefallCaveIcePerStepCallback(u8 taskId)
+{
+ s16 x, y;
+ u8 tileBehavior;
+ u16 *iceStepCount;
+ s16 *data = gTasks[taskId].data;
+ switch (data[1])
+ {
+ case 0:
+ PlayerGetDestCoords(&x, &y);
+ data[2] = x;
+ data[3] = y;
+ data[1] = 1;
+ break;
+ case 1:
+ PlayerGetDestCoords(&x, &y);
+ if (x != data[2] || y != data[3])
+ {
+ data[2] = x;
+ data[3] = y;
+ tileBehavior = MapGridGetMetatileBehaviorAt(x, y);
+ if (MetatileBehavior_IsThinIce(tileBehavior) == TRUE)
+ {
+ MarkIcefallCaveCoordVisited(x, y);
+ data[6] = 4;
+ data[1] = 2;
+ data[4] = x;
+ data[5] = y;
+ }
+ else if (MetatileBehavior_IsCrackedIce(tileBehavior) == TRUE)
+ {
+ data[6] = 4;
+ data[1] = 3;
+ data[4] = x;
+ data[5] = y;
+ }
+ }
+ break;
+ case 2:
+ if (data[6] != 0)
+ {
+ data[6]--;
+ }
+ else
+ {
+ x = data[4];
+ y = data[5];
+ PlaySE(SE_RU_BARI);
+ MapGridSetMetatileIdAt(x, y, 0x35a);
+ CurrentMapDrawMetatileAt(x, y);
+ data[1] = 1;
+ }
+ break;
+ case 3:
+ if (data[6] != 0)
+ {
+ data[6]--;
+ }
+ else
+ {
+ x = data[4];
+ y = data[5];
+ PlaySE(SE_RU_GASYAN);
+ MapGridSetMetatileIdAt(x, y, 0x35b);
+ CurrentMapDrawMetatileAt(x, y);
+ VarSet(VAR_0x4001, 1);
+ data[1] = 1;
+ }
+ break;
+ }
+}
+
+// This is leftover from pokeruby and effectively a no-op.
+static void AshGrassPerStepCallback(u8 taskId)
+{
+ s16 x, y;
+ u16 *ashGatherCount;
+ s16 *data = gTasks[taskId].data;
+ PlayerGetDestCoords(&x, &y);
+ if (x != data[1] || y != data[2])
+ {
+ data[1] = x;
+ data[2] = y;
+ if (MetatileBehavior_ReturnFalse_4((u8)MapGridGetMetatileBehaviorAt(x, y)))
+ {
+ if (MapGridGetMetatileIdAt(x, y) == 0x20a)
+ StartAshFieldEffect(x, y, 0x212, 4);
+ else
+ StartAshFieldEffect(x, y, 0x206, 4);
+ }
+ }
+}
+
+static void SetCrackedFloorHoleMetatile(s16 x, s16 y)
+{
+ MapGridSetMetatileIdAt(x, y, MapGridGetMetatileIdAt(x, y) == 0x22f ? 0x206 : 0x237);
+ CurrentMapDrawMetatileAt(x, y);
+}
+
+// This is leftover from pokeruby and effectively a no-op.
+static void CrackedFloorPerStepCallback(u8 taskId)
+{
+ s16 x, y;
+ u16 behavior;
+ s16 *data = gTasks[taskId].data;
+ PlayerGetDestCoords(&x, &y);
+ behavior = MapGridGetMetatileBehaviorAt(x, y);
+ if (data[4] != 0 && (--data[4]) == 0)
+ SetCrackedFloorHoleMetatile(data[5], data[6]);
+
+ if (data[7] != 0 && (--data[7]) == 0)
+ SetCrackedFloorHoleMetatile(data[8], data[9]);
+
+ if ((x != data[2] || y != data[3]))
+ {
+ data[2] = x;
+ data[3] = y;
+ if (MetatileBehavior_ReturnFalse_13(behavior))
+ {
+ if (GetPlayerSpeed() != 4)
+ VarSet(VAR_0x4030, 0);
+
+ if (data[4] == 0)
+ {
+ data[4] = 3;
+ data[5] = x;
+ data[6] = y;
+ }
+ else if (data[7] == 0)
+ {
+ data[7] = 3;
+ data[8] = x;
+ data[9] = y;
+ }
+ }
+ }
+}
+
+static void sub_806ED38(void)
+{
+ FlagSet(FLAG_SYS_POKEDEX_GET);
+ FlagSet(FLAG_SYS_POKEMON_GET);
+}
diff --git a/src/scrcmd.c b/src/scrcmd.c
index a88655e17..fad30a6a8 100644
--- a/src/scrcmd.c
+++ b/src/scrcmd.c
@@ -608,7 +608,7 @@ bool8 ScrCmd_setworldmapflag(struct ScriptContext *ctx)
bool8 ScrCmd_animateflash(struct ScriptContext *ctx)
{
- sub_807F028(ScriptReadByte(ctx));
+ AnimateFlash(ScriptReadByte(ctx));
ScriptContext1_Stop();
return TRUE;
}
diff --git a/src/seagallop.c b/src/seagallop.c
index cf07f9880..10ea97fec 100644
--- a/src/seagallop.c
+++ b/src/seagallop.c
@@ -303,7 +303,7 @@ static void Task_Seagallop_1(u8 taskId)
static void Task_Seagallop_2(u8 taskId)
{
ScrollBG();
- if (sub_8055FC4() && !gPaletteFade.active)
+ if (BGMusicStopped() && !gPaletteFade.active)
{
Task_Seagallop_3();
HelpSystem_Enable();