1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
#include "global.h"
#include "gflib.h"
#include "task.h"
/*
* Animates the screen as though it was a CRT monitor turning on or off.
*/
#define tState data[0]
#define tXSpeed data[1]
#define tYSpeed data[2]
#define tWin0Left data[3]
#define tWin0Right data[4]
#define tWin0Top data[5]
#define tWin0Bottom data[6]
#define tBldCntBak data[7]
#define tBldYBak data[8]
static void BeginPCScreenEffect(TaskFunc func, u16 a2, UNUSED u16 a3, u8 priority);
static void Task_PCScreenEffect_TurnOn(u8 taskId);
static void Task_PCScreenEffect_TurnOff(u8 taskId);
void BeginPCScreenEffect_TurnOn(u16 xspeed, u16 yspeed, u8 priority)
{
BeginPCScreenEffect(Task_PCScreenEffect_TurnOn, xspeed, yspeed, priority);
}
void BeginPCScreenEffect_TurnOff(u16 xspeed, u16 yspeed, u8 priority)
{
BeginPCScreenEffect(Task_PCScreenEffect_TurnOff, xspeed, yspeed, priority);
}
bool8 IsPCScreenEffectRunning_TurnOn(void)
{
return FuncIsActiveTask(Task_PCScreenEffect_TurnOn);
}
bool8 IsPCScreenEffectRunning_TurnOff(void)
{
return FuncIsActiveTask(Task_PCScreenEffect_TurnOff);
}
static void BeginPCScreenEffect(TaskFunc func, u16 speed, UNUSED u16 unused, u8 priority)
{
u8 taskId = CreateTask(func, priority);
gTasks[taskId].tState = 0;
gTasks[taskId].tXSpeed = speed == 0 ? 16 : speed;
gTasks[taskId].tYSpeed = speed == 0 ? 20 : speed; // Bug? should be the unused param, not speed
gTasks[taskId].func(taskId);
}
static void Task_PCScreenEffect_TurnOn(u8 taskId)
{
struct Task *task = &gTasks[taskId];
switch (task->tState)
{
case 0:
task->tWin0Left = 120;
task->tWin0Right = 120;
task->tWin0Top = 80;
task->tWin0Bottom = 81;
SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON);
SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE(task->tWin0Left, task->tWin0Right));
SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE(task->tWin0Top, task->tWin0Bottom));
SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR);
SetGpuReg(REG_OFFSET_WINOUT, 0);
break;
case 1:
task->tBldCntBak = GetGpuReg(REG_OFFSET_BLDCNT);
task->tBldYBak = GetGpuReg(REG_OFFSET_BLDY);
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG0 | BLDCNT_TGT1_BG1 | BLDCNT_TGT1_BG2 | BLDCNT_TGT1_BG3 | BLDCNT_TGT1_OBJ | BLDCNT_TGT1_BD | BLDCNT_EFFECT_LIGHTEN);
SetGpuReg(REG_OFFSET_BLDY, 16);
break;
case 2:
task->tWin0Left -= task->tXSpeed;
task->tWin0Right += task->tXSpeed;
if (task->tWin0Left <= 0 || task->tWin0Right >= DISPLAY_WIDTH)
{
task->tWin0Left = 0;
task->tWin0Right = DISPLAY_WIDTH;
SetGpuReg(REG_OFFSET_BLDY, 0);
SetGpuReg(REG_OFFSET_BLDCNT, task->tBldCntBak);
BlendPalettes(0xFFFFFFFF, 0, RGB_BLACK);
gPlttBufferFaded[0] = 0;
}
SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE(task->tWin0Left, task->tWin0Right));
if (task->tWin0Left)
return;
break;
case 3:
task->tWin0Top -= task->tYSpeed;
task->tWin0Bottom += task->tYSpeed;
if (task->tWin0Top <= 0 || task->tWin0Bottom >= DISPLAY_HEIGHT)
{
task->tWin0Top = 0;
task->tWin0Bottom = DISPLAY_HEIGHT;
ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON);
}
SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE(task->tWin0Top, task->tWin0Bottom));
if (task->tWin0Top)
return;
break;
default:
SetGpuReg(REG_OFFSET_BLDCNT, task->tBldCntBak);
DestroyTask(taskId);
return;
}
++task->tState;
}
static void Task_PCScreenEffect_TurnOff(u8 taskId)
{
struct Task *task = &gTasks[taskId];
switch (task->tState)
{
case 0:
gPlttBufferFaded[0] = 0;
break;
case 1:
task->tWin0Left = 0;
task->tWin0Right = DISPLAY_WIDTH;
task->tWin0Top = 0;
task->tWin0Bottom = DISPLAY_HEIGHT;
SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON);
SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE(task->tWin0Left, task->tWin0Right));
SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE(task->tWin0Top, task->tWin0Bottom));
SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR);
SetGpuReg(REG_OFFSET_WINOUT, 0);
break;
case 2:
task->tWin0Top += task->tYSpeed;
task->tWin0Bottom -= task->tYSpeed;
if (task->tWin0Top >= 80 || task->tWin0Bottom <= 81)
{
task->tWin0Top = 80;
task->tWin0Bottom = 81;
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG0 | BLDCNT_TGT1_BG1 | BLDCNT_TGT1_BG2 | BLDCNT_TGT1_BG3 | BLDCNT_TGT1_OBJ | BLDCNT_TGT1_BD | BLDCNT_EFFECT_LIGHTEN);
SetGpuReg(REG_OFFSET_BLDY, 16);
}
SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE(task->tWin0Top, task->tWin0Bottom));
if (task->tWin0Top != 80)
return;
break;
case 3:
task->tWin0Left += task->tXSpeed;
task->tWin0Right -= task->tXSpeed;
if (task->tWin0Left >= 120 || task->tWin0Right <= 120)
{
task->tWin0Left = 120;
task->tWin0Right = 120;
BlendPalettes(0xFFFFFFFF, 0x10, RGB_BLACK);
gPlttBufferFaded[0] = 0;
}
SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE(task->tWin0Left, task->tWin0Right));
if (task->tWin0Left != 120)
return;
break;
default:
ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON);
SetGpuReg(REG_OFFSET_BLDY, 0);
SetGpuReg(REG_OFFSET_BLDCNT, 0);
DestroyTask(taskId);
return;
}
++task->tState;
}
#undef tBldYBak
#undef tBldCntBak
#undef tWin0Bottom
#undef tWin0Top
#undef tWin0Right
#undef tWin0Left
#undef tYSpeed
#undef tXSpeed
#undef tState
|