mirror of
https://github.com/pret/pokeruby.git
synced 2026-10-09 01:58:43 -04:00
343 lines
7.8 KiB
C
343 lines
7.8 KiB
C
#include "global.h"
|
|
#include "event_data.h"
|
|
#include "field_camera.h"
|
|
#include "menu.h"
|
|
#include "palette.h"
|
|
#include "overworld.h"
|
|
#include "script.h"
|
|
#include "task.h"
|
|
#include "text.h"
|
|
#include "scanline_effect.h"
|
|
|
|
const static u16 sFlashLevelPixelRadii[] = { 200, 72, 56, 40, 24, 0 };
|
|
|
|
const s32 gMaxFlashLevel = 4;
|
|
|
|
const static struct ScanlineEffectParams sFlashEffectParams =
|
|
{
|
|
(void *)REG_ADDR_WIN0H,
|
|
((DMA_ENABLE | DMA_START_HBLANK | DMA_REPEAT | DMA_DEST_RELOAD) << 16) | 1,
|
|
1
|
|
};
|
|
|
|
static void SetFlashScanlineEffectWindowBoundary(u16 *dest, u32 y, s32 left, s32 right)
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
|
|
static void SetFlashScanlineEffectWindowBoundaries(u16 *dest, s32 centerX, s32 centerY, s32 radius)
|
|
{
|
|
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--;
|
|
}
|
|
}
|
|
}
|
|
|
|
#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 (data[0])
|
|
{
|
|
case 0:
|
|
SetFlashScanlineEffectWindowBoundaries(gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer], tFlashCenterX, tFlashCenterY, tCurFlashRadius);
|
|
data[0] = 1;
|
|
break;
|
|
case 1:
|
|
SetFlashScanlineEffectWindowBoundaries(gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer], tFlashCenterX, tFlashCenterY, tCurFlashRadius);
|
|
data[0] = 0;
|
|
tCurFlashRadius += tFlashRadiusDelta;
|
|
if (tCurFlashRadius > tDestFlashRadius)
|
|
{
|
|
if (tClearScanlineEffect == 1)
|
|
{
|
|
ScanlineEffect_Stop();
|
|
data[0] = 2;
|
|
}
|
|
else
|
|
{
|
|
DestroyTask(taskId);
|
|
}
|
|
}
|
|
break;
|
|
case 2:
|
|
ScanlineEffect_Clear();
|
|
DestroyTask(taskId);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void sub_80814E8(u8 taskId)
|
|
{
|
|
if (!FuncIsActiveTask(UpdateFlashLevelEffect))
|
|
{
|
|
EnableBothScriptContexts();
|
|
DestroyTask(taskId);
|
|
}
|
|
}
|
|
|
|
static void sub_8081510(void)
|
|
{
|
|
if (!FuncIsActiveTask(sub_80814E8))
|
|
CreateTask(sub_80814E8, 80);
|
|
}
|
|
|
|
static u8 sub_8081534(s32 centerX, s32 centerY, s32 initialFlashRadius, s32 destFlashRadius, s32 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 tCurFlashRadius
|
|
#undef tDestFlashRadius
|
|
#undef tFlashRadiusDelta
|
|
#undef tClearScanlineEffect
|
|
|
|
void sub_8081594(u8 flashLevel)
|
|
{
|
|
u8 curFlashLevel = Overworld_GetFlashLevel();
|
|
u8 value = 0;
|
|
if (!flashLevel)
|
|
value = 1;
|
|
sub_8081534(120, 80, sFlashLevelPixelRadii[curFlashLevel], sFlashLevelPixelRadii[flashLevel], value, 1);
|
|
sub_8081510();
|
|
ScriptContext2_Enable();
|
|
}
|
|
|
|
void WriteFlashScanlineEffectBuffer(u8 flashLevel)
|
|
{
|
|
if (flashLevel)
|
|
{
|
|
SetFlashScanlineEffectWindowBoundaries(&gScanlineEffectRegBuffers[0][0], 120, 80, sFlashLevelPixelRadii[flashLevel]);
|
|
CpuFastSet(&gScanlineEffectRegBuffers[0], &gScanlineEffectRegBuffers[1], 480);
|
|
}
|
|
}
|
|
|
|
static void sub_808161C(u8 a1)
|
|
{
|
|
int i;
|
|
u16 color[1];
|
|
|
|
if (!a1)
|
|
color[0] = 0x1F;
|
|
else
|
|
color[0] = 0x7C00;
|
|
|
|
for (i = 0; i < 16; i++)
|
|
{
|
|
LoadPalette(color, 0xF0 + i, 2);
|
|
}
|
|
}
|
|
|
|
static bool8 sub_8081658(u16 a1)
|
|
{
|
|
u8 lo = REG_BLDALPHA & 0xFF;
|
|
u8 hi = REG_BLDALPHA >> 8;
|
|
|
|
if (a1)
|
|
{
|
|
if (lo)
|
|
{
|
|
lo--;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (hi < 0x10)
|
|
{
|
|
hi++;
|
|
}
|
|
}
|
|
|
|
REG_BLDALPHA = (hi << 8) | lo;
|
|
|
|
if (lo == 0 && hi == 0x10)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static void sub_80816A8(u8 taskId)
|
|
{
|
|
s16 *data = gTasks[taskId].data;
|
|
|
|
switch (data[0])
|
|
{
|
|
case 0:
|
|
data[6] = REG_DISPCNT;
|
|
data[7] = REG_BLDCNT;
|
|
data[8] = REG_BLDALPHA;
|
|
data[9] = REG_WININ;
|
|
data[10] = REG_WINOUT;
|
|
REG_DISPCNT &= 0xBFFF;
|
|
REG_BLDCNT |= gUnknown_081E29E8[0];
|
|
REG_BLDALPHA = 1804;
|
|
REG_WININ = 63;
|
|
REG_WINOUT = 30;
|
|
SetFlashScanlineEffectWindowBoundaries(&gScanlineEffectRegBuffers[0][0], data[2], data[3], 1);
|
|
CpuFastSet(&gScanlineEffectRegBuffers[0], &gScanlineEffectRegBuffers[1], 480);
|
|
ScanlineEffect_SetParams(sFlashEffectParams);
|
|
data[0] = 1;
|
|
break;
|
|
case 1:
|
|
Menu_BlankWindowRect(0, 0, 29, 19);
|
|
sub_808161C(data[1]);
|
|
sub_8081534(data[2], data[3], 1, 160, 1, 2);
|
|
data[0] = 2;
|
|
break;
|
|
case 2:
|
|
if (!FuncIsActiveTask(UpdateFlashLevelEffect))
|
|
{
|
|
EnableBothScriptContexts();
|
|
data[0] = 3;
|
|
}
|
|
break;
|
|
case 3:
|
|
InstallCameraPanAheadCallback();
|
|
SetCameraPanningCallback(NULL);
|
|
data[5] = 0;
|
|
data[4] = 4;
|
|
data[0] = 4;
|
|
break;
|
|
case 4:
|
|
data[4]--;
|
|
if (!data[4])
|
|
{
|
|
s32 panning;
|
|
data[4] = 4;
|
|
data[5] ^= 1;
|
|
if (data[5])
|
|
panning = 4;
|
|
else
|
|
panning = -4;
|
|
SetCameraPanning(0, panning);
|
|
}
|
|
break;
|
|
case 6:
|
|
InstallCameraPanAheadCallback();
|
|
data[4] = 8;
|
|
data[0] = 7;
|
|
break;
|
|
case 7:
|
|
data[4]--;
|
|
if (!data[4])
|
|
{
|
|
data[4] = 8;
|
|
data[5] ^= 1;
|
|
if (sub_8081658(data[5]) == TRUE)
|
|
data[0] = 5;
|
|
}
|
|
break;
|
|
case 5:
|
|
Menu_EraseWindowRect(0, 0, 29, 19);
|
|
LoadFontDefaultPalette(&gMenuTextWindowTemplate);
|
|
REG_WIN0H = 255;
|
|
REG_DISPCNT = data[6];
|
|
REG_BLDCNT = data[7];
|
|
REG_BLDALPHA = data[8];
|
|
REG_WININ = data[9];
|
|
REG_WINOUT = data[10];
|
|
EnableBothScriptContexts();
|
|
DestroyTask(taskId);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void sub_80818A4(void)
|
|
{
|
|
u8 taskId = CreateTask(sub_80816A8, 80);
|
|
s16 *data = gTasks[taskId].data;
|
|
|
|
if (gSpecialVar_Result == 0)
|
|
{
|
|
data[1] = 0;
|
|
data[2] = 104;
|
|
}
|
|
else if (gSpecialVar_Result == 1)
|
|
{
|
|
data[1] = 1;
|
|
data[2] = 104;
|
|
}
|
|
else if (gSpecialVar_Result == 2)
|
|
{
|
|
data[1] = 0;
|
|
data[2] = 120;
|
|
}
|
|
else
|
|
{
|
|
data[1] = 1;
|
|
data[2] = 120;
|
|
}
|
|
|
|
data[3] = 80;
|
|
}
|
|
|
|
void sub_80818FC(void)
|
|
{
|
|
u8 taskId = FindTaskIdByFunc(sub_80816A8);
|
|
gTasks[taskId].data[0] = 6;
|
|
}
|
|
|
|
static void task50_0807F0C8(u8);
|
|
|
|
void sub_8081924(void)
|
|
{
|
|
Overworld_FadeOutMapMusic();
|
|
CreateTask(task50_0807F0C8, 80);
|
|
}
|
|
|
|
static void task50_0807F0C8(u8 taskId)
|
|
{
|
|
if (BGMusicStopped() == TRUE)
|
|
{
|
|
DestroyTask(taskId);
|
|
EnableBothScriptContexts();
|
|
}
|
|
}
|