1
2 #include "screeneffect.h"
3
4 #include "graphics/Renderer.h"
5 #include "nx.h"
6 #include "sound/SoundManager.h"
7 using namespace NXE::Graphics;
8 #include "map.h"
9
10 SE_FlashScreen flashscreen;
11 SE_Starflash starflash;
12 SE_Fade fade;
13
14 /*
15 void c------------------------------() {}
16 */
17
18 // FlashScreen simply flashes the screen white several times,
19 // and is used in various places, such as when Misery casts spells.
Start(void)20 void SE_FlashScreen::Start(void)
21 {
22 timer = -1;
23 flashes_left = 5;
24 flashstate = true;
25
26 enabled = true;
27 }
28
Draw(void)29 void SE_FlashScreen::Draw(void)
30 {
31 if (++timer >= 2)
32 {
33 timer = 0;
34 flashstate ^= 1;
35
36 if (!flashstate)
37 {
38 if (--flashes_left <= 0)
39 enabled = false;
40 }
41 }
42
43 if (flashstate)
44 Renderer::getInstance()->clearScreen(0xff, 0xff, 0xff);
45 }
46
47 /*
48 void c------------------------------() {}
49 */
50
51 // Starflash is a full-screen white explosion in the shape of a '+',
52 // used when some bosses are defeated.
53
Start(int x,int y)54 void SE_Starflash::Start(int x, int y)
55 {
56 NXE::Sound::SoundManager::getInstance()->playSfx(NXE::Sound::SFX::SND_EXPLOSION1);
57 enabled = true;
58 state = 0;
59 centerx = x;
60 centery = y;
61 size = speed = 0;
62 }
63
Draw(void)64 void SE_Starflash::Draw(void)
65 {
66 SE_Starflash *const &star = this;
67 int scr_x1, scr_y1, scr_x2, scr_y2;
68 int rel_x, rel_y;
69
70 if (state == 0)
71 { // flash getting bigger
72 star->speed += (1 * CSFI);
73 star->size += star->speed;
74 }
75 else
76 { // flash getting smaller
77 star->size -= (star->size >> 3);
78
79 if (star->size < 255)
80 {
81 enabled = false;
82 return;
83 }
84 }
85
86 // draw the flash
87 rel_x = (star->centerx - map.displayed_xscroll);
88 rel_y = (star->centery - map.displayed_yscroll);
89
90 // draw a horizontal bar
91 scr_y1 = (rel_y - star->size) / CSFI;
92 scr_y2 = (rel_y + star->size) / CSFI;
93 Renderer::getInstance()->fillRect(0, scr_y1, Renderer::getInstance()->screenWidth, scr_y2, 255, 255, 255);
94
95 if (star->state == 0)
96 {
97 // draw a vertical bar
98 scr_x1 = (rel_x - starflash.size) / CSFI;
99 scr_x2 = (rel_x + starflash.size) / CSFI;
100 Renderer::getInstance()->fillRect(scr_x1, 0, scr_x2, Renderer::getInstance()->screenHeight, 255, 255, 255);
101
102 // once it's big enough, switch to making it smaller
103 if (star->size > (1280 * CSFI))
104 {
105 star->size = (Renderer::getInstance()->screenHeight * CSFI);
106 star->state = 1;
107 }
108 }
109 }
110
111 /*
112 void c------------------------------() {}
113 */
114
115 #define FADE_LAST_FRAME 15
116
117 // Fade is the fade-in/out used on every stage transistion/TRA.
118 // Unlike other effects, it is drawn underneath the textboxes and Nikumaru counter,
119 // and so isn't drawn from ScreenEffects::Draw().
120
SE_Fade()121 SE_Fade::SE_Fade()
122 {
123 state = FS_NO_FADE;
124 enabled = false;
125 }
126
127 // start a fade in or out.
128 // fadedir: either FADE_IN or FADE_OUT
129 // sweepdir: direction to "sweep" the fade
130 // spr: the sprite to use for the fading
Start(int fadedir,int sweepdir,int spr)131 void SE_Fade::Start(int fadedir, int sweepdir, int spr)
132 {
133 if (fadedir == FADE_OUT)
134 {
135 // when fading out, the directions are reversed
136 switch (sweepdir)
137 {
138 case FADE_LEFT:
139 sweepdir = FADE_RIGHT;
140 break;
141 case FADE_RIGHT:
142 sweepdir = FADE_LEFT;
143 break;
144 case FADE_UP:
145 sweepdir = FADE_DOWN;
146 break;
147 case FADE_DOWN:
148 sweepdir = FADE_UP;
149 break;
150 }
151 }
152
153 state = FS_FADING;
154 enabled = true;
155
156 fade.sprite = spr;
157
158 fade.fadedir = fadedir;
159 fade.sweepdir = sweepdir;
160 fade.curframe = (fadedir == FADE_OUT) ? -FADE_LAST_FRAME : FADE_LAST_FRAME;
161 }
162
Draw(void)163 void SE_Fade::Draw(void)
164 {
165 int x, y;
166
167 if (state == FS_NO_FADE)
168 {
169 return;
170 }
171 else if (state == FS_FADED_OUT)
172 {
173 Renderer::getInstance()->clearScreen(DK_BLUE);
174 return;
175 }
176
177 int frame = fade.curframe;
178 switch (fade.sweepdir)
179 {
180 case FADE_RIGHT:
181 for (x = 0; x < Renderer::getInstance()->screenWidth; x += 16)
182 {
183 if (frame >= 0)
184 {
185 if (frame > FADE_LAST_FRAME)
186 frame = FADE_LAST_FRAME;
187
188 for (y = 0; y < Renderer::getInstance()->screenHeight; y += 16)
189 Renderer::getInstance()->sprites.drawSprite(x, y, fade.sprite, frame);
190 }
191 frame++;
192 }
193 break;
194
195 case FADE_LEFT:
196 for (x = Renderer::getInstance()->screenWidth - 1; x >= -16; x -= 16)
197 {
198 if (frame >= 0)
199 {
200 if (frame > FADE_LAST_FRAME)
201 frame = FADE_LAST_FRAME;
202
203 for (y = 0; y < Renderer::getInstance()->screenHeight; y += 16)
204 Renderer::getInstance()->sprites.drawSprite(x, y, fade.sprite, frame);
205 }
206 frame++;
207 }
208 break;
209
210 case FADE_DOWN:
211 for (y = 0; y < Renderer::getInstance()->screenHeight; y += 16)
212 {
213 if (frame >= 0)
214 {
215 if (frame > FADE_LAST_FRAME)
216 frame = FADE_LAST_FRAME;
217
218 for (x = 0; x < Renderer::getInstance()->screenWidth; x += 16)
219 Renderer::getInstance()->sprites.drawSprite(x, y, fade.sprite, frame);
220 }
221 frame++;
222 }
223 break;
224
225 case FADE_UP:
226 for (y = Renderer::getInstance()->screenHeight - 1; y >= -16; y -= 16)
227 {
228 if (frame >= 0)
229 {
230 if (frame > FADE_LAST_FRAME)
231 frame = FADE_LAST_FRAME;
232
233 for (x = 0; x < Renderer::getInstance()->screenWidth; x += 16)
234 Renderer::getInstance()->sprites.drawSprite(x, y, fade.sprite, frame);
235 }
236 frame++;
237 }
238 break;
239
240 case FADE_CENTER:
241 {
242 int startframe = fade.curframe;
243 int centerx = (Renderer::getInstance()->screenWidth / 2) - 8;
244 int centery = (Renderer::getInstance()->screenHeight / 2) - 8;
245
246 for (x = 0; x < centerx + 16; x += 16)
247 {
248 frame = startframe;
249
250 for (y = 0; y < centery + 16; y += 16)
251 {
252 if (frame >= 0)
253 {
254 if (frame > FADE_LAST_FRAME)
255 frame = FADE_LAST_FRAME;
256
257 Renderer::getInstance()->sprites.drawSprite(centerx + x, centery + y, fade.sprite, frame);
258 Renderer::getInstance()->sprites.drawSprite(centerx - x, centery + y, fade.sprite, frame);
259 Renderer::getInstance()->sprites.drawSprite(centerx + x, centery - y, fade.sprite, frame);
260 Renderer::getInstance()->sprites.drawSprite(centerx - x, centery - y, fade.sprite, frame);
261 }
262
263 frame++;
264 }
265
266 startframe++;
267 }
268 }
269 break;
270 }
271
272 if (fade.fadedir == FADE_OUT)
273 {
274 fade.curframe++;
275 if (fade.curframe > FADE_LAST_FRAME)
276 state = FS_FADED_OUT;
277 }
278 else
279 { // fading in--terminate fade when done
280 fade.curframe--;
281 if (fade.curframe < -20)
282 {
283 state = FS_NO_FADE;
284 enabled = false;
285 }
286 }
287 }
288
set_full(int dir)289 void SE_Fade::set_full(int dir)
290 {
291 if (dir == FADE_OUT)
292 {
293 state = FS_FADED_OUT;
294
295 fade.fadedir = FADE_OUT;
296 fade.sweepdir = FADE_RIGHT; // doesn't matter
297 fade.curframe = FADE_LAST_FRAME;
298 fade.sprite = SPR_FADE_DIAMOND;
299 }
300 else
301 {
302 state = FS_NO_FADE;
303 enabled = false;
304 }
305 }
306
getstate(void)307 int SE_Fade::getstate(void)
308 {
309 return this->state;
310 }
311
312 /*
313 void c------------------------------() {}
314 */
315
Draw(void)316 void ScreenEffects::Draw(void)
317 {
318 if (starflash.enabled)
319 starflash.Draw();
320
321 if (flashscreen.enabled)
322 flashscreen.Draw();
323 }
324
Stop()325 void ScreenEffects::Stop()
326 {
327 starflash.enabled = false;
328 flashscreen.enabled = false;
329 }
330