diff options
author | PikalaxALT <pikalaxalt@gmail.com> | 2020-01-06 13:59:20 -0500 |
---|---|---|
committer | PikalaxALT <pikalaxalt@gmail.com> | 2020-01-06 13:59:20 -0500 |
commit | ccb5c0f324e2b9002a687c9111b2675bc6bd101d (patch) | |
tree | 84d587d63154d9a8da3e9983aae2042f09767737 /src | |
parent | 498ad1e6af6b219aa54b827e59325b6fbcb54343 (diff) | |
parent | 26f7ba482384ad4f63063797a527b7fb33572aa1 (diff) |
Merge branch 'master' of github.com:pret/pokefirered into region_map
Diffstat (limited to 'src')
-rw-r--r-- | src/field_fadetransition.c | 14 | ||||
-rw-r--r-- | src/field_screen_effect.c | 265 | ||||
-rw-r--r-- | src/field_tasks.c | 293 | ||||
-rw-r--r-- | src/scrcmd.c | 2 | ||||
-rw-r--r-- | src/seagallop.c | 2 |
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(); |