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