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