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