1 /*
2  * XBoing - An X11 blockout style computer game
3  *
4  * (c) Copyright 1993, 1994, 1995, Justin C. Kibell, All Rights Reserved
5  *
6  * The X Consortium, and any party obtaining a copy of these files from
7  * the X Consortium, directly or indirectly, is granted, free of charge, a
8  * full and unrestricted irrevocable, world-wide, paid up, royalty-free,
9  * nonexclusive right and license to deal in this software and
10  * documentation files (the "Software"), including without limitation the
11  * rights to use, copy, modify, merge, publish, distribute, sublicense,
12  * and/or sell copies of the Software, and to permit persons who receive
13  * copies from any such party to do so.  This license includes without
14  * limitation a license to do the foregoing actions under any patents of
15  * the party supplying this software to the X Consortium.
16  *
17  * In no event shall the author be liable to any party for direct, indirect,
18  * special, incidental, or consequential damages arising out of the use of
19  * this software and its documentation, even if the author has been advised
20  * of the possibility of such damage.
21  *
22  * The author specifically disclaims any warranties, including, but not limited
23  * to, the implied warranties of merchantability and fitness for a particular
24  * purpose.  The software provided hereunder is on an "AS IS" basis, and the
25  * author has no obligation to provide maintenance, support, updates,
26  * enhancements, or modifications.
27  */
28 
29 /*
30  * =========================================================================
31  *
32  * $Id: sfx.c,v 1.1.1.1 1994/12/16 01:36:45 jck Exp $
33  * $Source: /usr5/legends/jck/xb/master/xboing/sfx.c,v $
34  * $Revision: 1.1.1.1 $
35  * $Date: 1994/12/16 01:36:45 $
36  *
37  * $Log: sfx.c,v $
38  * Revision 1.1.1.1  1994/12/16  01:36:45  jck
39  * The XBoing distribution requires configuration management. This is why the
40  * cvs utility is being used. This is the initial import of all source etc..
41  *
42  *
43  * =========================================================================
44  */
45 
46 /*
47  *  Include file dependencies:
48  */
49 
50 #include <stdio.h>
51 #include <stdlib.h>
52 #include <stddef.h>
53 #include <X11/Xlib.h>
54 #include <X11/Xutil.h>
55 #include <X11/Xos.h>
56 #include <xpm.h>
57 
58 #include "error.h"
59 #include "init.h"
60 #include "stage.h"
61 #include "score.h"
62 #include "blocks.h"
63 #include "ball.h"
64 #include "main.h"
65 #include "mess.h"
66 #include "misc.h"
67 #include "intro.h"
68 
69 #include "sfx.h"
70 
71 /*
72  *  Internal macro definitions:
73  */
74 
75 #define SHAKE_DELAY			5
76 #define NUM_SCAT 			10
77 #define RANDY(range) 		(rand() % (range))
78 
79 /*
80  *  Internal type declarations:
81  */
82 
83 /*
84  *  Internal variable declarations:
85  */
86 
87 static int sfxEndFrame, useSfx;
88 int modeSfx;
89 static int xscat[NUM_SCAT] = { 1, 9, 3, 6, 2, 4, 0, 7, 5, 8 };
90 static int yscat[NUM_SCAT] = { 2, 1, 0, 8, 6, 4, 9, 3, 7, 5 };
91 
92 #if NeedFunctionPrototypes
useSpecialEffects(int state)93 void useSpecialEffects(int state)
94 #else
95 void useSpecialEffects(state)
96 	int state;
97 #endif
98 {
99 	/* Set the state of the special effects - True = use */
100 	/* Of course - if the sfx are not possible then no effect */
101 	useSfx = state;
102 }
103 
104 #if NeedFunctionPrototypes
getSpecialEffects(Display * display)105 int getSpecialEffects(Display *display)
106 #else
107 int getSpecialEffects(display)
108 	Display *display;
109 #endif
110 {
111 	/* Only shake around if the server has backing store on */
112 	if (DoesBackingStore(XDefaultScreenOfDisplay(display)) != Always)
113 		return -1;
114 
115 	/* Return special effects state - on or off */
116 	return useSfx;
117 }
118 
119 #if NeedFunctionPrototypes
changeSfxMode(int newMode)120 void changeSfxMode(int newMode)
121 #else
122 void changeSfxMode(newMode)
123 	int newMode;
124 #endif
125 {
126 	modeSfx = newMode;
127 }
128 
129 #if NeedFunctionPrototypes
currentSfxMode(void)130 int currentSfxMode(void)
131 #else
132 int currentSfxMode()
133 #endif
134 {
135 	/* Return the current special effects mode */
136 	return modeSfx;
137 }
138 
139 #if NeedFunctionPrototypes
resetEffect(Display * display)140 static void resetEffect(Display *display)
141 #else
142 static void resetEffect(display)
143 	Display *display;
144 #endif
145 {
146 	/* Just re-centre window return */
147 	modeSfx = SFX_NONE;
148 	XMoveWindow(display, playWindow, 35, 60);
149 }
150 
151 #if NeedFunctionPrototypes
WindowBlindEffect(Display * display,Window window)152 int WindowBlindEffect(Display *display, Window window)
153 #else
154 int WindowBlindEffect(display, window)
155 	Display *display;
156 	Window window;
157 #endif
158 {
159 	int x, i;
160 
161 	/* Does the user want special effects */
162 	if (useSfx == False)
163 	{
164 		/* No - Just return out */
165 		resetEffect(display);
166 		return False;
167 	}
168 
169 	XSetBackground(display, gcsfx, black);
170 
171 	/* Draw a blinds effect where little doors close over screen */
172 	for (i = 0; i <= (PLAY_WIDTH / 8); i++)
173 		for (x = 0; x <= PLAY_WIDTH; x += (PLAY_WIDTH / 8))
174 			XCopyArea(display, bufferWindow, window, gc,
175 				x+i, 0, 1, PLAY_HEIGHT, x+i, 0);
176 
177 	/* End of special effect - reset off */
178 	resetEffect(display);
179 	return False;
180 }
181 
182 
183 #if NeedFunctionPrototypes
WindowStaticEffect(Display * display,Window window,int w,int h)184 int WindowStaticEffect(Display *display, Window window, int w, int h)
185 #else
186 int WindowStaticEffect(display, window, w, h)
187 	Display *display;
188 	Window window;
189 	int w, h;
190 #endif
191 {
192 	static int start = True;
193 
194 	if (start)
195 	{
196 		SetSfxEndFrame(frame + 50);
197 		start = False;
198 	}
199 
200 	/* Do somehting in here */
201 
202 	if (frame >= sfxEndFrame)
203 	{
204 		/* End of special effect - reset off */
205 		resetEffect(display);
206 		start = True;
207 		return False;
208 	}
209 
210 	return True;
211 }
212 
213 #if NeedFunctionPrototypes
WindowShatterEffect(Display * display,Window window)214 int WindowShatterEffect(Display *display, Window window)
215 #else
216 int WindowShatterEffect(display, window)
217 	Display *display;
218 	Window window;
219 #endif
220 {
221     int offx, offy, sizeWidth, sizeHeight;
222     int srcx, srcy, destx, desty;
223 
224 	/* Does the user want special effects */
225 	if (useSfx == False)
226 	{
227 		/* No - Just return out */
228 		resetEffect(display);
229 		return False;
230 	}
231 
232 
233     offx = RANDY(NUM_SCAT);
234     offy = RANDY(NUM_SCAT);
235 	sizeWidth = 200;
236 	sizeHeight = 200;
237 
238 	/* Spend a bit of time scattering new pixmap into view */
239 	/* Original idea for this effect from xjewel */
240     for (srcx = 0; srcx < NUM_SCAT; srcx++)
241     {
242     	for (srcy = 0; srcy < NUM_SCAT; srcy++)
243         {
244             for (destx = 0; destx <= 4; destx++)
245 			{
246             	for (desty = 0; desty <= 5; desty++)
247                 {
248 					XCopyArea(display, bufferWindow, window, gc,
249                     	(destx * sizeWidth) +
250                         	xscat[(srcx + srcy + offx) % NUM_SCAT]
251 							* (sizeWidth / NUM_SCAT),
252 
253                     	(desty * sizeHeight) +
254                         	yscat[(srcy + offy) % NUM_SCAT]
255 							* (sizeHeight / NUM_SCAT),
256 
257                     	(sizeWidth  / NUM_SCAT),
258 						(sizeHeight / NUM_SCAT),
259 
260                     	(destx * sizeWidth) +
261                         	xscat[(srcx + srcy + offx) % NUM_SCAT]
262 							* (sizeWidth / NUM_SCAT),
263 
264                     	(desty * sizeHeight) +
265                         	yscat[(srcy + offy) % NUM_SCAT]
266 							* (sizeHeight / NUM_SCAT));
267                	}
268 			}
269         }
270     }
271 
272 	/* End of special effect - reset off */
273 	resetEffect(display);
274 	return False;
275 }
276 
277 #if NeedFunctionPrototypes
WindowFadeEffect(Display * display,Window window,int w,int h)278 int WindowFadeEffect(Display *display, Window window, int w, int h)
279 #else
280 int WindowFadeEffect(display, window, w, h)
281 	Display *display;
282 	Window window;
283 	int w, h;
284 #endif
285 {
286 	static int done = False;
287 	static int first = True;
288 	int y;
289 	int x;
290 	static int i = 0;
291 
292 	/* Does the user want special effects */
293 	if (useSfx == False)
294 	{
295 		/* No - Just return out */
296 		resetEffect(display);
297 		return False;
298 	}
299 
300 	if (first == True)
301 	{
302 		first = False;
303 		XSetForeground(display, gcsfx, black);
304 		XSetBackground(display, gcsfx, black);
305 		XSetWindowBorder(display, window, red);
306 	}
307 
308 	/* Draw vertical lines */
309 	for (x = i; x <= w; x += 12)
310 		XDrawLine(display, window, gcsfx, x, 0, x, h);
311 
312 	/* Draw horizontal lines */
313 	for (y = i; y <= h; y += 12)
314 		XDrawLine(display, window, gcsfx, 0, y, w, y);
315 
316 	/* Fill in grid slowly */
317 	i++;
318 	if (i > 12) done = True;
319 
320 	if (done == True)
321 	{
322 		/* End of special effect - reset off */
323 		done = False;
324 		first = True;
325 		i = 0;
326 		resetEffect(display);
327 		return False;
328 	}
329 
330 	/* Keep efect going please */
331 	return True;
332 }
333 
334 #if NeedFunctionPrototypes
WindowShakeEffect(Display * display,Window window)335 int WindowShakeEffect(Display *display, Window window)
336 #else
337 int WindowShakeEffect(display, window)
338 	Display *display;
339 	Window window;
340 #endif
341 {
342 	static int x = 35;
343 	static int y = 60;
344 	int xi, yi;
345 
346 	/* Does the user want special effects */
347 	if (useSfx == False)
348 	{
349 		/* No - Just return out */
350 		resetEffect(display);
351 		return False;
352 	}
353 
354 	/* Only shake around if the server has backing store on */
355 	if (DoesBackingStore(XDefaultScreenOfDisplay(display)) != Always)
356 	{
357 		resetEffect(display);
358 		return False;
359 	}
360 
361 	if (frame >= sfxEndFrame)
362 	{
363 		/* End of special effect - reset off */
364 		resetEffect(display);
365 		return False;
366 	}
367 
368 	if ((frame % SHAKE_DELAY) != 0) return True;
369 
370 	XMoveWindow(display, window, x, y);
371 	XFlush(display);
372 
373 	xi = (rand() % 6) - 3;
374 	yi = (rand() % 6) - 3;
375 	x = xi + 35; y = yi + 60;
376 
377 	return True;
378 }
379 
380 #if NeedFunctionPrototypes
SetSfxEndFrame(int endFrame)381 void SetSfxEndFrame(int endFrame)
382 #else
383 void SetSfxEndFrame(endFrame)
384 	int endFrame;
385 #endif
386 {
387 	sfxEndFrame = endFrame;
388 }
389 
390 #if NeedFunctionPrototypes
BorderGlow(Display * display,Window window)391 void BorderGlow(Display *display, Window window)
392 #else
393 void BorderGlow(display, window)
394     Display *display;
395     Window window;
396 #endif
397 {
398     static int i = 0;
399     static int d = 1;
400     static int t = 1;
401 
402 	/* Does the user want special effects */
403 	if (useSfx == False)
404 	{
405 		/* No - Just return out */
406 		return;
407 	}
408 
409 	/* Only update every n frames */
410     if ((frame % 40) == 0)
411     {
412 		/* Alternate between the red and the green ranges */
413         if (t > 0)
414             XSetWindowBorder(display, playWindow, reds[i]);
415         else
416             XSetWindowBorder(display, playWindow, greens[i]);
417 
418 		/* Ok change range or fade down again */
419         if (i == 6)
420         {
421             d = -1;
422             t *= -1;
423         }
424 
425         if (i == 0)
426             d = 1;
427 
428 		/* Next range index */
429         i += d;
430      }
431 }
432 
433 #if NeedFunctionPrototypes
ResetBorderGlow(Display * display,Window window)434 void ResetBorderGlow(Display *display, Window window)
435 #else
436 void ResetBorderGlow(display, window)
437     Display *display;
438     Window window;
439 #endif
440 {
441     XSetWindowBorder(display, playWindow, red);
442 }
443 
444 #if NeedFunctionPrototypes
FadeAwayArea(Display * display,Window window,int x,int y,int w,int h)445 void FadeAwayArea(Display *display, Window window, int x, int y, int w, int h)
446 #else
447 void FadeAwayArea(display, window, x, y, w, h)
448 	Display *display;
449 	Window window;
450 	int x, y, w, h;
451 #endif
452 {
453 	int i, x1, y1, step;
454 
455 	step = w / 15;
456 
457 	/* Fade away an area slowly so it looks good */
458 	for (i = 0; i <= step; i++)
459 	{
460 		/* Draw vertical lines */
461 		for (x1 = i; x1 <= w; x1 += 15)
462 			XClearArea(display, window, x + x1, y, 1, h, False);
463 
464 		/* Draw horizontal lines */
465 		for (y1 = i; y1 <= h; y1 += 15)
466 			XClearArea(display, window,  x, y + y1, w, 1, False);
467 	}
468 }
469