1 /***************************************************************************
2                           extras.c  -  description
3                              -------------------
4     begin                : Sun Sep 9 2001
5     copyright            : (C) 2001 by Michael Speck
6     email                : kulkanie@gmx.net
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 
18 #include "lbreakout.h"
19 #include "../game/game.h"
20 #include "bricks.h"
21 #include "shrapnells.h"
22 #include "player.h"
23 #include "paddle.h"
24 #include "frame.h"
25 
26 extern Player *cur_player;
27 extern SDL_Surface *stk_display;
28 extern SDL_Rect stk_drect;
29 extern SDL_Surface *offscreen;
30 extern SDL_Surface *bkgnd; /* background + frame */
31 extern SDL_Surface *offscreen_backup;
32 extern int ball_w, ball_dia;
33 extern SDL_Surface *brick_pic;
34 extern Brick bricks[MAP_WIDTH][MAP_HEIGHT];
35 extern SDL_Surface *extra_pic; /* graphics */
36 extern SDL_Surface *extra_shadow;
37 extern SDL_Surface *paddle_pic, *weapon_pic;
38 extern SDL_Surface *ball_pic;
39 extern SDL_Surface *shot_pic;
40 extern StkFont *display_font;
41 extern SDL_Surface *wall_pic;
42 extern int shadow_size;
43 #ifdef AUDIO_ENABLED
44 extern StkSound *wav_score, *wav_metal, *wav_std, *wav_wall, *wav_joker;
45 extern StkSound *wav_goldshower, *wav_life_up;
46 extern StkSound *wav_speedup, *wav_speeddown;
47 extern StkSound *wav_chaos, *wav_darkness, *wav_ghost;
48 extern StkSound *wav_timeadd, *wav_expl_ball, *wav_weak_ball;
49 extern StkSound *wav_bonus_magnet, *wav_malus_magnet, *wav_disable;
50 extern StkSound *wav_attach; /* handled by balls.c */
51 extern StkSound *wav_expand, *wav_shrink, *wav_frozen;
52 #endif
53 extern Game *game; /* client game context */
54 extern int paddle_ch;
55 extern int ball_pic_x_offset;
56 
57 /*
58 ====================================================================
59 Locals
60 ====================================================================
61 */
62 
63 /*
64 ====================================================================
65 Public
66 ====================================================================
67 */
68 
69 /* Play sounds and handle graphical effects. */
client_handle_collected_extra(Paddle * paddle,int extra_type)70 void client_handle_collected_extra( Paddle *paddle, int extra_type )
71 {
72 	int i, j;
73 	int tm = game->diff->time_mod; /* time modifier */
74 
75 #ifdef AUDIO_ENABLED
76         int px = paddle->x+(paddle->w>>1);
77 #endif
78 	Extra *ex;
79 
80 	switch (extra_type) {
81 		case EX_JOKER:
82 #ifdef AUDIO_ENABLED
83 			stk_sound_play_x( px, wav_joker );
84 #endif
85 			list_reset( game->extras );
86 			while ( ( ex = list_next( game->extras ) ) ) {
87 				stk_display_store_rect( &ex->update_rect );
88 				list_delete_current( game->extras );
89 			}
90 			break;
91 		case EX_SCORE200:
92 		case EX_SCORE500:
93 		case EX_SCORE1000:
94 		case EX_SCORE2000:
95 		case EX_SCORE5000:
96 		case EX_SCORE10000:
97 #ifdef AUDIO_ENABLED
98 			stk_sound_play_x( px, wav_score );
99 #endif
100 			break;
101 		case EX_GOLDSHOWER:
102 			paddle->extra_time[EX_GOLDSHOWER] += TIME_GOLDSHOWER * tm;
103 			paddle->extra_active[EX_GOLDSHOWER] = 1;
104 #ifdef AUDIO_ENABLED
105 			stk_sound_play_x( px, wav_goldshower );
106 #endif
107 			break;
108 		case EX_LIFE:
109 			if ( game->game_type == GT_LOCAL ) {
110 				if ( paddle->player->lives < game->diff->max_lives ) {
111 					paddle->player->lives++;
112 					frame_add_life();
113 				}
114 			}
115 			break;
116 		case EX_SHORTEN:
117 #ifdef AUDIO_ENABLED
118 			stk_sound_play_x( px, wav_shrink );
119 #endif
120 			paddle_init_resize( paddle, -1);
121 			break;
122 		case EX_LENGTHEN:
123 #ifdef AUDIO_ENABLED
124 			stk_sound_play_x( px, wav_expand );
125 #endif
126 			paddle_init_resize( paddle, 1);
127 			break;
128 		case EX_BALL:
129 #ifdef AUDIO_ENABLED
130 			stk_sound_play_x( px, wav_std );
131 #endif
132 			break;
133 		case EX_WALL:
134 			paddle->extra_time[EX_WALL] += TIME_WALL * tm;
135 			if ( paddle->extra_active[EX_WALL] ) {
136 #ifdef AUDIO_ENABLED
137 				stk_sound_play_x( px, wav_std );
138 #endif
139 				break;
140 			}
141 			paddle->extra_active[extra_type] = 1;
142 			paddle->wall_alpha = 0;
143 #ifdef AUDIO_ENABLED
144 			stk_sound_play_x( px, wav_wall );
145 #endif
146 			break;
147 		case EX_METAL:
148 			game->extra_time[EX_METAL] += TIME_METAL * tm;
149 			game->extra_active[extra_type] = 1;
150 			ball_pic_x_offset = ball_w;
151 #ifdef AUDIO_ENABLED
152 			stk_sound_play_x( px, wav_metal );
153 #endif
154 			/* other ball extras are disabled */
155 			if ( game->extra_active[EX_EXPL_BALL] ) {
156 				game->extra_active[EX_EXPL_BALL] = 0;
157 				game->extra_time[EX_EXPL_BALL] = 0;
158 			}
159 			if ( game->extra_active[EX_WEAK_BALL] ) {
160 				game->extra_active[EX_WEAK_BALL] = 0;
161 				game->extra_time[EX_WEAK_BALL] = 0;
162 			}
163 			break;
164 		case EX_FROZEN:
165 			paddle->extra_time[EX_FROZEN] = TIME_FROZEN * tm;
166 			paddle->extra_active[extra_type] = 1;
167 			paddle->pic_y_offset = paddle_ch*2;
168 			paddle->frozen = 1; /* the server sided paddle is blocked
169 					       so does the same with the local copy */
170 #ifdef AUDIO_ENABLED
171 			stk_sound_play_x( px, wav_frozen );
172 #endif
173 			break;
174 		case EX_WEAPON:
175 			paddle->extra_time[EX_WEAPON] += TIME_WEAPON * tm;
176 			paddle->extra_active[extra_type] = 1;
177 			weapon_install( paddle, 1 );
178 #ifdef AUDIO_ENABLED
179 			stk_sound_play_x( px, wav_std );
180 #endif
181 			break;
182 		case EX_SLIME:
183 			paddle->extra_time[EX_SLIME] += TIME_SLIME * tm;
184 			paddle->extra_active[extra_type] = 1;
185 			if ( !paddle->frozen )
186 				paddle->pic_y_offset = paddle_ch;
187 #ifdef AUDIO_ENABLED
188 			stk_sound_play_x( px, wav_attach );
189 #endif
190 			break;
191 		case EX_FAST:
192 #ifdef AUDIO_ENABLED
193 			stk_sound_play_x( px, wav_speedup );
194 #endif
195 			if ( game->extra_active[EX_SLOW] ) {
196 				game->extra_time[EX_SLOW] = 0;
197 				game->extra_active[EX_SLOW] = 0;
198 			}
199 			game->extra_time[EX_FAST] += TIME_FAST * tm;
200 			game->extra_active[extra_type] = 1;
201 			break;
202 		case EX_SLOW:
203 #ifdef AUDIO_ENABLED
204 			stk_sound_play_x( px, wav_speeddown );
205 #endif
206 			if ( game->extra_active[EX_FAST] ) {
207 				game->extra_time[EX_FAST] = 0;
208 				game->extra_active[EX_FAST] = 0;
209 			}
210 			game->extra_time[EX_SLOW] += TIME_SLOW * tm;
211 			game->extra_active[extra_type] = 1;
212 			break;
213 		case EX_CHAOS:
214 #ifdef AUDIO_ENABLED
215 			stk_sound_play_x( px, wav_chaos );
216 #endif
217 			game->extra_time[EX_CHAOS] += TIME_CHAOS * tm;
218 			game->extra_active[extra_type] = 1;
219 			break;
220 		case EX_DARKNESS:
221 #ifdef AUDIO_ENABLED
222 			stk_sound_play_x( px, wav_darkness );
223 #endif
224 			game->extra_time[EX_DARKNESS] += TIME_DARKNESS * tm;
225 			if ( game->extra_active[EX_DARKNESS] ) break;
226 			/* backup offscreen and turn it black */
227 			stk_surface_fill( offscreen, 0,0,-1,-1, 0x0 );
228 			stk_surface_fill( stk_display, 0,0,-1,-1, 0x0 );
229 			stk_display_store_rect( 0 );
230 			/* set alpha keys to 128 */
231 			SDL_SetAlpha( paddle_pic, SDL_SRCALPHA, 128 );
232 			SDL_SetAlpha( weapon_pic, SDL_SRCALPHA, 128 );
233 			SDL_SetAlpha( extra_pic, SDL_SRCALPHA, 128 );
234 			SDL_SetAlpha( ball_pic, SDL_SRCALPHA, 128 );
235 			SDL_SetAlpha( shot_pic, SDL_SRCALPHA, 128 );
236 			SDL_SetAlpha( display_font->surface, SDL_SRCALPHA, 128 );
237 			/* use dark explosions */
238 			exps_set_dark( 1 );
239 			game->extra_active[extra_type] = 1;
240 			break;
241 		case EX_GHOST_PADDLE:
242 #ifdef AUDIO_ENABLED
243 			stk_sound_play_x( px, wav_ghost );
244 #endif
245 			paddle->extra_time[EX_GHOST_PADDLE] += TIME_GHOST_PADDLE * tm;
246 			paddle->extra_active[extra_type] = 1;
247 			paddle_set_invis( paddle, 1 );
248 			break;
249 		case EX_TIME_ADD:
250 #ifdef AUDIO_ENABLED
251 			stk_sound_play_x( px, wav_timeadd );
252 #endif
253 			for ( i = 0; i < EX_NUMBER; i++ )
254 				if ( game->extra_time[i] )
255 					game->extra_time[i] += 7000 * tm;
256 			for ( i = 0; i < EX_NUMBER; i++ ) {
257 				for ( j = 0; j < game->paddle_count; j++ )
258 					if ( game->paddles[j]->extra_time[i] )
259 						game->paddles[j]->extra_time[i] += 7000 * tm;
260 			}
261 			break;
262 		case EX_EXPL_BALL:
263 #ifdef AUDIO_ENABLED
264 			stk_sound_play_x( px, wav_expl_ball );
265 #endif
266 			ball_pic_x_offset = ball_w*2;
267 			game->extra_time[EX_EXPL_BALL] += TIME_EXPL_BALL * tm;
268 			game->extra_active[extra_type] = 1;
269 			/* other ball extras are disabled */
270 			if ( game->extra_active[EX_METAL] ) {
271 				game->extra_active[EX_METAL] = 0;
272 				game->extra_time[EX_METAL] = 0;
273 			}
274 			if ( game->extra_active[EX_WEAK_BALL] ) {
275 				game->extra_active[EX_WEAK_BALL] = 0;
276 				game->extra_time[EX_WEAK_BALL] = 0;
277 			}
278 			break;
279 		case EX_WEAK_BALL:
280 #ifdef AUDIO_ENABLED
281 			stk_sound_play_x( px, wav_weak_ball );
282 #endif
283 			ball_pic_x_offset = ball_w*3;
284 			game->extra_time[EX_WEAK_BALL] += TIME_WEAK_BALL * tm;
285 			game->extra_active[extra_type] = 1;
286 			/* other ball extras are disabled */
287 			if ( game->extra_active[EX_METAL] ) {
288 				game->extra_active[EX_METAL] = 0;
289 				game->extra_time[EX_METAL] = 0;
290 			}
291 			if ( game->extra_active[EX_EXPL_BALL] ) {
292 				game->extra_active[EX_EXPL_BALL] = 0;
293 				game->extra_time[EX_EXPL_BALL] = 0;
294 			}
295 			break;
296 		case EX_BONUS_MAGNET:
297 #ifdef AUDIO_ENABLED
298 			stk_sound_play_x( px, wav_bonus_magnet );
299 #endif
300 			paddle_set_attract( paddle, ATTRACT_BONUS );
301 			paddle->extra_time[EX_BONUS_MAGNET] += TIME_BONUS_MAGNET * tm;
302 			paddle->extra_active[extra_type] = 1;
303 			if ( paddle->extra_active[EX_MALUS_MAGNET] ) {
304 				paddle->extra_active[EX_MALUS_MAGNET] = 0;
305 				paddle->extra_time[EX_MALUS_MAGNET] = 0;
306 			}
307 			break;
308 		case EX_MALUS_MAGNET:
309 #ifdef AUDIO_ENABLED
310 			stk_sound_play_x( px, wav_malus_magnet );
311 #endif
312 			paddle_set_attract( paddle, ATTRACT_MALUS );
313 			paddle->extra_time[EX_MALUS_MAGNET] += TIME_MALUS_MAGNET * tm;
314 			paddle->extra_active[extra_type] = 1;
315 			if ( paddle->extra_active[EX_BONUS_MAGNET] ) {
316 				paddle->extra_active[EX_BONUS_MAGNET] = 0;
317 				paddle->extra_time[EX_BONUS_MAGNET] = 0;
318 			}
319 			break;
320 		case EX_DISABLE:
321 #ifdef AUDIO_ENABLED
322 			stk_sound_play_x( px, wav_disable );
323 #endif
324 			/* set all active extra times to 1 so they will expire next
325 			   prog cycle */
326 			for ( i = 0; i < EX_NUMBER; i++ )
327 				if ( game->extra_time[i] )
328 					game->extra_time[i] = 1;
329 			for ( i = 0; i < EX_NUMBER; i++ ) {
330 				for ( j = 0; j < game->paddle_count; j++ )
331 					if ( game->paddles[j]->extra_time[i] )
332 						game->paddles[j]->extra_time[i] = 1;
333 			}
334 			break;
335 	}
336 }
337 /*
338 ====================================================================
339 Show, hide extras
340 ====================================================================
341 */
extras_hide()342 void extras_hide()
343 {
344     ListEntry  *entry = game->extras->head->next;
345     Extra       *ex;
346     while ( entry != game->extras->tail ) {
347         ex = entry->item;
348         entry = entry->next;
349         stk_surface_blit( offscreen,
350             (int)ex->x, (int)ex->y,
351             BRICK_WIDTH + shadow_size, BRICK_HEIGHT + shadow_size,
352             stk_display, (int)ex->x, (int)ex->y );
353         ex->update_rect = stk_drect;
354 	stk_display_store_rect( &ex->update_rect );
355     }
356 }
extras_show_shadow()357 void extras_show_shadow()
358 {
359     ListEntry  *entry = game->extras->head->next;
360     Extra       *extra;
361     while ( entry != game->extras->tail ) {
362         extra = entry->item;
363         stk_surface_clip( stk_display, 0,0,
364             stk_display->w - BRICK_WIDTH, stk_display->h );
365         stk_surface_alpha_blit(
366             extra_shadow, extra->type * BRICK_WIDTH, 0,
367             BRICK_WIDTH, BRICK_HEIGHT,
368             stk_display, (int)extra->x + shadow_size, (int)extra->y + shadow_size,
369             ((int)extra->alpha)>>1 );
370         stk_surface_clip( stk_display, 0,0,-1,-1 );
371         entry = entry->next;
372     }
373 }
extras_show()374 void extras_show()
375 {
376     ListEntry  *entry = game->extras->head->next;
377     Extra       *ex;
378     int         x, y;
379     while ( entry != game->extras->tail ) {
380         ex = entry->item;
381         entry = entry->next;
382         x = (int)ex->x; y = (int)ex->y;
383         stk_surface_alpha_blit( extra_pic, ex->offset, 0,
384             BRICK_WIDTH, BRICK_HEIGHT, stk_display, x, y, ex->alpha );
385 #if 0
386         if ( x < ex->update_rect.x ) {
387             /* movement to left */
388             ex->update_rect.w += ex->update_rect.x - x;
389             ex->update_rect.x = x;
390         }
391         else
392             /* movement to right */
393             ex->update_rect.w += x - ex->update_rect.x;
394         if ( ex->dir == -1 ) {
395             /* movement up */
396             ex->update_rect.h += ex->update_rect.y - y;
397             ex->update_rect.y = y;
398             if ( ex->update_rect.y < 0 ) {
399                 ex->update_rect.h += ex->update_rect.y;
400                 ex->update_rect.y = 0;
401             }
402         }
403         else {
404             /* movement down */
405             ex->update_rect.h += y - ex->update_rect.y;
406             if ( ex->update_rect.y + ex->update_rect.h >= stk_display->h )
407                 ex->update_rect.h = stk_display->h - ex->update_rect.y;
408         }
409         stk_display_store_rect( &ex->update_rect );
410 #endif
411 	ex->update_rect.x = x;
412 	ex->update_rect.y = y;
413 	ex->update_rect.w = BRICK_WIDTH + shadow_size;
414 	ex->update_rect.h = BRICK_HEIGHT + shadow_size;
415         stk_display_store_rect( &ex->update_rect );
416     }
417 }
extras_alphashow(int alpha)418 void extras_alphashow( int alpha )
419 {
420     ListEntry  *entry = game->extras->head->next;
421     Extra       *ex;
422     int         x, y;
423     while ( entry != game->extras->tail ) {
424         ex = entry->item;
425         x = (int)ex->x;
426         y = (int)ex->y;
427         stk_surface_alpha_blit( extra_pic, ex->type * BRICK_WIDTH, 0,
428             BRICK_WIDTH, BRICK_HEIGHT, stk_display, x, y, alpha );
429         stk_display_store_rect( &ex->update_rect );
430         entry = entry->next;
431     }
432 }
433 
434 /* move the extras as in extras_update but do not collect them */
client_extras_update(int ms)435 void client_extras_update( int ms )
436 {
437 	Extra       *ex;
438 	int i, j;
439 	int magnets;
440 	Paddle *magnet;
441 
442 	/* check extra_time of limited extras */
443 	/* general extras */
444 	for ( i = 0; i < EX_NUMBER; i++ )
445 		if ( game->extra_time[i] ) {
446 			if ( (game->extra_time[i] -= ms) <= 0 ) {
447 				game->extra_time[i] = 0;
448 				/* expired */
449 				switch ( i ) {
450 					case EX_EXPL_BALL:
451 					case EX_WEAK_BALL:
452 					case EX_METAL:
453 						ball_pic_x_offset = 0;
454 						break;
455 					case EX_DARKNESS:
456 						/* restore offscreen */
457 						stk_surface_blit( bkgnd, 0,0,-1,-1, offscreen, 0,0 );
458 						bricks_draw();
459 						if ( game->game_type == GT_LOCAL )
460 							frame_draw_lives( cur_player->lives,
461 									  game->diff->max_lives );
462 						/* back to screen */
463 						stk_surface_blit(
464 							offscreen, 0,0,-1,-1,
465 							stk_display, 0,0 );
466 						stk_display_store_rect( 0 );
467 						/* set alpha keys to OPAQUE */
468 						SDL_SetAlpha( paddle_pic, 0,0 );
469 						SDL_SetAlpha( extra_pic, 0,0 );
470 						SDL_SetAlpha( ball_pic, 0,0 );
471 						SDL_SetAlpha( shot_pic, 0,0 );
472 						SDL_SetAlpha( display_font->surface, 0,0 );
473 						/* use bright explosions */
474 						exps_set_dark( 0 );
475 						break;
476 				}
477 				/* set deactivated */
478 				game->extra_active[i] = 0;
479 			}
480 		}
481 	/* paddlized extras */
482 	for ( j = 0; j < game->paddle_count; j++ )
483 	for ( i = 0; i < EX_NUMBER; i++ )
484 		/* extra_time of wall is updated in client_walls_update() */
485 		if ( game->paddles[j]->extra_time[i] && i != EX_WALL )
486 		if ( (game->paddles[j]->extra_time[i] -= ms) <= 0 ) {
487 			game->paddles[j]->extra_time[i] = 0;
488 			/* expired */
489 			switch ( i ) {
490 				case EX_FROZEN:
491 				case EX_SLIME:
492 					if ( game->paddles[j]->extra_time[EX_SLIME] > 0 )
493 						game->paddles[j]->pic_y_offset = paddle_ch;
494 					else
495 						game->paddles[j]->pic_y_offset = 0;
496 					game->paddles[j]->frozen = 0;
497 					break;
498 				case EX_WEAPON:
499 					weapon_install( game->paddles[j], 0 );
500 					break;
501 				case EX_GHOST_PADDLE:
502 					paddle_set_invis( game->paddles[j], 0 );
503 					break;
504 				case EX_BONUS_MAGNET:
505 				case EX_MALUS_MAGNET:
506 					paddle_set_attract( game->paddles[j], ATTRACT_NONE );
507 					break;
508 			}
509 			/* set deactivated */
510 			game->paddles[j]->extra_active[i] = 0; /* wall is handled in wall_...() */
511 		}
512 
513 	/* move extras and check if paddle was hit */
514 	list_reset( game->extras );
515 	while ( ( ex = list_next( game->extras ) ) ) {
516 		/* if only one paddle has a magnet active all extras will
517 		 * be attracted by this paddle else the extras 'dir' is used
518 		 */
519 		magnets = 0; magnet = 0;
520 		for ( i = 0; i < game->paddle_count; i++ )
521 			if ( paddle_check_attract( game->paddles[i], ex->type ) ) {
522 				magnets++;
523 				magnet = game->paddles[i]; /* last magnet */
524 			}
525 		if ( magnets != 1 ) {
526 			/* either no or more than one magnet so use default */
527 			if ( ex->dir > 0 )
528 				ex->y += 0.05 * ms;
529 			else
530 				ex->y -= 0.05 * ms;
531 		}
532 		else {
533 			/* 'magnet' is the paddle that will attract this extra */
534 			if ( magnet->type == PADDLE_TOP )
535 				ex->y -= 0.05 * ms;
536 			else
537 				ex->y += 0.05 * ms;
538 			if ( ex->x + ( BRICK_WIDTH >> 1 ) < magnet->x + ( magnet->w >> 1 ) ) {
539 				ex->x += 0.05 * ms;
540 				if ( ex->x + ( BRICK_WIDTH >> 1 ) > magnet->x + ( magnet->w >> 1 ) )
541 					ex->x = magnet->x + ( magnet->w >> 1 ) - ( BRICK_WIDTH >> 1 );
542 			}
543 			else {
544 				ex->x -= 0.05 * ms;
545 				if ( ex->x + ( BRICK_WIDTH >> 1 ) < magnet->x + ( magnet->w >> 1 ) )
546 					ex->x = magnet->x + ( magnet->w >> 1 ) - ( BRICK_WIDTH >> 1 );
547 			}
548 		}
549 		if ( !game->extra_active[EX_DARKNESS] ) {
550 			if ( ex->alpha < 255 ) {
551 				ex->alpha += 0.25 * ms;
552 				if (ex->alpha > 255)
553 					ex->alpha = 255;
554 			}
555 		}
556 		else {
557 			if ( ex->alpha < 128 ) {
558 				ex->alpha += 0.25 * ms;
559 				if (ex->alpha > 128)
560 					ex->alpha = 128;
561 			}
562 		}
563 		/* if out of screen forget this extra */
564 		if ( ex->y >= stk_display->h || ex->y + BRICK_HEIGHT < 0 ) {
565 			stk_display_store_rect( &ex->update_rect );
566 			list_delete_current( game->extras );
567 			continue;
568 		}
569 		for ( j = 0; j < game->paddle_count; j++ ) {
570 			/* contact with paddle core ? */
571 			if ( paddle_solid( game->paddles[j] ) )
572 			if ( ex->x + BRICK_WIDTH > game->paddles[j]->x )
573 			if ( ex->x < game->paddles[j]->x + game->paddles[j]->w - 1 )
574 			if ( ex->y + BRICK_HEIGHT > game->paddles[j]->y )
575 			if ( ex->y < game->paddles[j]->y + game->paddles[j]->h ) {
576 				/* remove extra but don't handle it */
577 				stk_display_store_rect( &ex->update_rect );
578 				list_delete_current( game->extras );
579 			}
580 		}
581 	}
582 }
583 
584 /* wall */
walls_hide()585 void walls_hide()
586 {
587     int j;
588     for ( j = 0; j < game->paddle_count; j++ )
589         if ( game->paddles[j]->extra_active[EX_WALL] ) {
590             stk_surface_blit( offscreen, BRICK_WIDTH, game->paddles[j]->wall_y,
591                 wall_pic->w, wall_pic->h,
592                 stk_display, BRICK_WIDTH, game->paddles[j]->wall_y );
593             stk_display_store_drect();
594         }
595 }
walls_show()596 void walls_show()
597 {
598     int j;
599     for ( j = 0; j < game->paddle_count; j++ )
600         if ( game->paddles[j]->extra_active[EX_WALL] )
601             stk_surface_alpha_blit( wall_pic, 0,0,
602                 wall_pic->w, wall_pic->h,
603                 stk_display, BRICK_WIDTH, game->paddles[j]->wall_y,
604                 (int)game->paddles[j]->wall_alpha );
605 }
walls_alphashow(int alpha)606 void walls_alphashow( int alpha )
607 {
608     int j;
609     for ( j = 0; j < game->paddle_count; j++ )
610         if ( game->paddles[j]->extra_active[EX_WALL] )
611             stk_surface_alpha_blit( wall_pic, 0,0,
612                 wall_pic->w, wall_pic->h,
613                 stk_display, BRICK_WIDTH, game->paddles[j]->wall_y,
614                 alpha );
615 }
client_walls_update(int ms)616 void client_walls_update( int ms )
617 {
618 	int j;
619 
620 	for ( j = 0; j < game->paddle_count; j++ )
621 		if ( game->paddles[j]->extra_active[EX_WALL] ) {
622 			if ( game->paddles[j]->extra_time[EX_WALL] > 0 ) {
623 				if ( (game->paddles[j]->extra_time[EX_WALL] -= ms) < 0 )
624 					game->paddles[j]->extra_time[EX_WALL] = 0;
625 				/* still appearing? */
626 				if (game->paddles[j]->wall_alpha < 255)
627 				if ( (game->paddles[j]->wall_alpha += 0.25 * ms) > 255 )
628 					game->paddles[j]->wall_alpha = 255;
629 			}
630 			else
631 			if ( (game->paddles[j]->wall_alpha -= 0.25 * ms) < 0 ) {
632 				game->paddles[j]->wall_alpha = 0;
633 				game->paddles[j]->extra_active[EX_WALL] = 0;
634 			}
635 		}
636 }
637 
638