- removed alpha from tile since it isn't needed
[supertux.git] / src / player.cpp
1 //
2 // C Implementation: player/tux
3 //
4 // Description:
5 //
6 //
7 // Author: Tobias Glaesser <tobi.web@gmx.de> & Bill Kendrick, (C) 2004
8 //
9 // Copyright: See COPYING file that comes with this distribution
10 //
11 //
12
13 #include "gameloop.h"
14 #include "globals.h"
15 #include "player.h"
16 #include "defines.h"
17 #include "scene.h"
18 #include "tile.h"
19 #include "screen.h"
20
21 texture_type tux_life;
22 texture_type tux_right[3];
23 texture_type tux_left[3];
24 texture_type bigtux_right[3];
25 texture_type bigtux_left[3];
26 texture_type bigtux_right_jump;
27 texture_type bigtux_left_jump;
28 texture_type ducktux_right;
29 texture_type ducktux_left;
30 texture_type skidtux_right;
31 texture_type skidtux_left;
32 texture_type firetux_right[3];
33 texture_type firetux_left[3];
34 texture_type bigfiretux_right[3];
35 texture_type bigfiretux_left[3];
36 texture_type bigfiretux_right_jump;
37 texture_type bigfiretux_left_jump;
38 texture_type duckfiretux_right;
39 texture_type duckfiretux_left;
40 texture_type skidfiretux_right;
41 texture_type skidfiretux_left;
42 texture_type cape_right[2];
43 texture_type cape_left[2];
44 texture_type bigcape_right[2];
45 texture_type bigcape_left[2];
46
47 void player_input_init(player_input_type* pplayer_input)
48 {
49   pplayer_input->down = UP;
50   pplayer_input->fire = UP;
51   pplayer_input->left = UP;
52   pplayer_input->old_fire = UP;
53   pplayer_input->right = UP;
54   pplayer_input->up = UP;
55 }
56
57 void
58 Player::init()
59 {
60   base.width = 32;
61   base.height = 32;
62
63   size = SMALL;
64   got_coffee = false;
65
66   // FIXME: Make the start position configurable via the levelfile
67   base.x = 100;
68   base.y = 240;
69   
70   base.xm = 0;
71   base.ym = 0;
72   old_base = base;
73   dir = RIGHT;
74   duck = false;
75
76   dying   = DYING_NOT;
77   jumping = false;
78
79   frame_main = 0;
80   frame_ = 0;
81   lives = 3;
82   score = 0;
83   distros = 0;
84
85   player_input_init(&input);
86
87   keymap.jump  = SDLK_UP;
88   keymap.duck  = SDLK_DOWN;
89   keymap.left  = SDLK_LEFT;
90   keymap.right = SDLK_RIGHT;
91   keymap.fire  = SDLK_LCTRL;
92
93   timer_init(&invincible_timer,true);
94   timer_init(&skidding_timer,true);
95   timer_init(&safe_timer,true);
96   timer_init(&frame_timer,true);
97   physic_init(&hphysic);
98   physic_init(&vphysic);
99 }
100
101 int
102 Player::key_event(SDLKey key, int state)
103 {
104   if(key == keymap.right)
105     {
106       input.right = state;
107       return true;
108     }
109   else if(key == keymap.left)
110     {
111       input.left = state;
112       return true;
113     }
114   else if(key == keymap.jump)
115     {
116       input.up = state;
117       return true;
118     }
119   else if(key == keymap.duck)
120     {
121       input.down = state;
122       return true;
123     }
124   else if(key == keymap.fire)
125     {
126       input.fire = state;
127       return true;
128     }
129   else
130     return false;
131 }
132
133 void
134 Player::level_begin()
135 {
136   base.x  = 100;
137   base.y  = 240;
138   base.xm = 0;
139   base.ym = 0;
140   old_base = base;
141
142   player_input_init(&input);
143
144   timer_init(&invincible_timer,true);
145   timer_init(&skidding_timer,true);
146   timer_init(&safe_timer,true);
147   timer_init(&frame_timer,true);
148   physic_init(&hphysic);
149   physic_init(&vphysic);
150 }
151
152 void
153 Player::action()
154 {
155   bool jumped_in_solid = false;
156
157   /* --- HANDLE TUX! --- */
158
159   handle_input();
160
161   /* Move tux: */
162
163   previous_base = base;
164
165   base.x += base.xm * frame_ratio;
166   base.y += base.ym * frame_ratio;
167   
168   collision_swept_object_map(&old_base,&base);
169
170   keep_in_bounds();
171
172   /* Land: */
173
174   if (!dying)
175     {
176       if( !on_ground())
177         {
178           if(under_solid())
179             {
180               physic_set_state(&vphysic,PH_VT);
181               physic_set_start_vy(&vphysic,0);
182               jumped_in_solid = true;
183             }
184           else
185             {
186               if(!physic_is_set(&vphysic))
187                 {
188                   physic_set_state(&vphysic,PH_VT);
189                   physic_set_start_vy(&vphysic,0);
190                 }
191             }
192           base.ym = physic_get_velocity(&vphysic);
193         }
194       else
195         {
196           /* Land: */
197
198           if (base.ym > 0)
199             {
200               base.y = (int)(((int)base.y / 32) * 32);
201               base.ym = 0;
202             }
203
204           physic_init(&vphysic);
205
206           /* Reset score multiplier (for multi-hits): */
207
208           score_multiplier = 1;
209         }
210
211       if(jumped_in_solid)
212         {
213           if (isbrick(base.x, base.y) ||
214               isfullbox(base.x, base.y))
215             {
216               trygrabdistro(base.x, base.y - 32,BOUNCE);
217               trybumpbadguy(base.x, base.y - 64);
218
219               trybreakbrick(base.x, base.y, size == SMALL);
220
221               bumpbrick(base.x, base.y);
222               tryemptybox(base.x, base.y, RIGHT);
223             }
224
225           if (isbrick(base.x+ 31, base.y) ||
226               isfullbox(base.x+ 31, base.y))
227             {
228               trygrabdistro(base.x+ 31, base.y - 32,BOUNCE);
229               trybumpbadguy(base.x+ 31, base.y - 64);
230
231               if(size == BIG)
232                 trybreakbrick(base.x+ 31, base.y, size == SMALL);
233
234               bumpbrick(base.x+ 31, base.y);
235               tryemptybox(base.x+ 31, base.y, LEFT);
236             }
237         }
238
239       grabdistros();
240
241       if (jumped_in_solid)
242         {
243           ++base.y;
244           ++old_base.y;
245           if(on_ground())
246             {
247               /* Make sure jumping is off. */
248               jumping = false;
249             }
250         }
251
252     }
253
254   timer_check(&safe_timer);
255
256
257   /* ---- DONE HANDLING TUX! --- */
258
259   /* Handle invincibility timer: */
260
261
262   if (get_current_music() == HERRING_MUSIC && !timer_check(&invincible_timer))
263     {
264       /*
265          no, we are no more invincible
266          or we were not in invincible mode
267          but are we in hurry ?
268        */
269
270
271       if (timer_get_left(&time_left) < TIME_WARNING)
272         {
273           /* yes, we are in hurry
274              stop the herring_song, prepare to play the correct
275              fast level_song !
276            */
277           set_current_music(HURRYUP_MUSIC);
278         }
279       else
280         {
281           set_current_music(LEVEL_MUSIC);
282         }
283
284       /* start playing it */
285       play_current_music();
286     }
287
288   /* Handle skidding: */
289
290   timer_check(&skidding_timer);
291
292   /* End of level? */
293
294   if (base.x >= endpos && endpos != 0)
295     {
296       next_level = 1;
297     }
298
299 }
300
301 bool
302 Player::on_ground()
303 {
304   return ( issolid(base.x + base.width / 2, base.y + base.height) ||
305            issolid(base.x + 1, base.y + base.height) ||
306            issolid(base.x + base.width - 1, base.y + base.height)  );
307 }
308
309 bool
310 Player::under_solid()
311 {
312   return ( issolid(base.x + base.width / 2, base.y) ||
313            issolid(base.x + 1, base.y) ||
314            issolid(base.x + base.width - 1, base.y)  );
315 }
316
317 void
318 Player::handle_horizontal_input(int newdir)
319 {
320   if ((newdir ? (base.xm < -SKID_XM) : (base.xm > SKID_XM)) && !timer_started(&skidding_timer) &&
321       dir == !newdir && on_ground())
322     {
323       timer_start(&skidding_timer, SKID_TIME);
324
325       play_sound(sounds[SND_SKID], SOUND_CENTER_SPEAKER);
326
327     }
328   dir = newdir;
329
330
331   if ((newdir ? (base.xm < 0) : (base.xm > 0)) && !isice(base.x, base.y + base.height) &&
332       !timer_started(&skidding_timer))
333     {
334       base.xm = 0;
335     }
336
337   if (!duck)
338     {
339       if (dir == newdir)
340         {
341           /* Facing the direction we're jumping?  Go full-speed: */
342
343           if (input.fire == UP)
344             {
345               base.xm = base.xm + ( newdir ? WALK_SPEED : -WALK_SPEED) * frame_ratio;
346
347               if(newdir)
348                 {
349                   if (base.xm > MAX_WALK_XM)
350                     base.xm = MAX_WALK_XM;
351                 }
352               else
353                 {
354                   if (base.xm < -MAX_WALK_XM)
355                     base.xm = -MAX_WALK_XM;
356                 }
357             }
358           else if ( input.fire == DOWN)
359             {
360               base.xm = base.xm + ( newdir ? RUN_SPEED : -RUN_SPEED) * frame_ratio;
361
362               if(newdir)
363                 {
364                   if (base.xm > MAX_RUN_XM)
365                     base.xm = MAX_RUN_XM;
366                 }
367               else
368                 {
369                   if (base.xm < -MAX_RUN_XM)
370                     base.xm = -MAX_RUN_XM;
371                 }
372             }
373           else
374             {
375               /* Not facing the direction we're jumping?
376                  Go half-speed: */
377
378               base.xm = base.xm + ( newdir ? (WALK_SPEED / 2) : -(WALK_SPEED / 2)) * frame_ratio;
379
380               if(newdir)
381                 {
382                   if (base.xm > MAX_WALK_XM / 2)
383                     base.xm = MAX_WALK_XM / 2;
384                 }
385               else
386                 {
387                   if (base.xm < -MAX_WALK_XM / 2)
388                     base.xm = -MAX_WALK_XM / 2;
389                 }
390             }
391         }
392
393     }
394 }
395
396 void
397 Player::handle_vertical_input()
398 {
399   if(input.up == DOWN)
400     {
401       if (on_ground())
402         {
403           if(!physic_is_set(&vphysic))
404             {
405               physic_set_state(&vphysic,PH_VT);
406               physic_set_start_vy(&vphysic,5.5);
407               --base.y;
408               jumping = true;
409               if (size == SMALL)
410                 play_sound(sounds[SND_JUMP], SOUND_CENTER_SPEAKER);
411               else
412                 play_sound(sounds[SND_BIGJUMP], SOUND_CENTER_SPEAKER);
413             }
414         }
415     }
416   else if(input.up == UP && jumping)
417     {
418       if (on_ground())
419         {
420           physic_init(&vphysic);
421           jumping = false;
422         }
423       else
424         {
425           jumping = false;
426           if(physic_is_set(&vphysic))
427             {
428               if(physic_get_velocity(&vphysic) < 0.)
429                 {
430                   physic_set_state(&vphysic,PH_VT);
431                   physic_set_start_vy(&vphysic,0);
432                 }
433             }
434           else
435             {
436               if(!physic_is_set(&vphysic))
437                 {
438                   physic_set_state(&vphysic,PH_VT);
439                 }
440             }
441         }
442     }
443 }
444
445 void
446 Player::handle_input()
447 {
448   /* Handle key and joystick state: */
449   if(duck == false)
450     {
451       if (input.right == DOWN && input.left == UP)
452         {
453           handle_horizontal_input(RIGHT);
454         }
455       else if (input.left == DOWN && input.right == UP)
456         {
457           handle_horizontal_input(LEFT);
458         }
459       else
460         {
461           if(base.xm > 0)
462             {
463               base.xm = (int)(base.xm - frame_ratio);
464               if(base.xm < 0)
465                 base.xm = 0;
466             }
467           else if(base.xm < 0)
468             {
469               base.xm = (int)(base.xm + frame_ratio);
470               if(base.xm > 0)
471                 base.xm = 0;
472             }
473         }
474     }
475
476   /* Jump/jumping? */
477
478   if ( input.up == DOWN || (input.up == UP && jumping))
479     {
480       handle_vertical_input();
481     }
482
483   /* Shoot! */
484
485   if (input.fire == DOWN && input.old_fire == UP && got_coffee)
486     {
487       add_bullet(base.x, base.y, base.xm, dir);
488     }
489
490
491   /* Duck! */
492
493   if (input.down == DOWN)
494     {
495       if (size == BIG && duck != true)
496         {
497           duck = true;
498           base.height = 32;
499           base.y += 32;
500         }
501     }
502   else
503     {
504       if (size == BIG && duck)
505         {
506           /* Make sure we're not standing back up into a solid! */
507           base.height = 64;
508           base.y -= 32;
509
510           if (!collision_object_map(&base) /*issolid(base.x + 16, base.y - 16)*/)
511             {
512               duck = false;
513               base.height = 64;
514               old_base.y -= 32;
515               old_base.height = 64;
516             }
517           else
518             {
519               base.height = 32;
520               base.y += 32;
521             }
522         }
523       else
524         {
525           duck = false;
526         }
527     }
528
529   /* (Tux): */
530
531   if(!timer_check(&frame_timer))
532     {
533       timer_start(&frame_timer,25);
534       if (input.right == UP && input.left == UP)
535         {
536           frame_main = 1;
537           frame_ = 1;
538         }
539       else
540         {
541           if ((input.fire == DOWN && (global_frame_counter % 2) == 0) ||
542               (global_frame_counter % 4) == 0)
543             frame_main = (frame_main + 1) % 4;
544
545           frame_ = frame_main;
546
547           if (frame_ == 3)
548             frame_ = 1;
549         }
550     }
551
552 }
553
554 void
555 Player::grabdistros()
556 {
557   /* Grab distros: */
558   if (!dying)
559     {
560       trygrabdistro(base.x, base.y, NO_BOUNCE);
561       trygrabdistro(base.x+ 31, base.y, NO_BOUNCE);
562
563       trygrabdistro(base.x, base.y + base.height, NO_BOUNCE);
564       trygrabdistro(base.x+ 31, base.y + base.height, NO_BOUNCE);
565
566       if(size == BIG)
567         {
568           trygrabdistro(base.x, base.y + base.height / 2, NO_BOUNCE);
569           trygrabdistro(base.x+ 31, base.y + base.height / 2, NO_BOUNCE);
570         }
571
572     }
573
574   /* Enough distros for a One-up? */
575   if (distros >= DISTROS_LIFEUP)
576     {
577       distros = distros - DISTROS_LIFEUP;
578       if(lives < MAX_LIVES)
579         lives++;
580       /*We want to hear the sound even, if MAX_LIVES is reached*/
581       play_sound(sounds[SND_LIFEUP], SOUND_CENTER_SPEAKER);
582     }
583 }
584
585 void
586 Player::draw()
587 {
588   if (!timer_started(&safe_timer) || (global_frame_counter % 2) == 0)
589     {
590       if (size == SMALL)
591         {
592           if (timer_started(&invincible_timer))
593             {
594               /* Draw cape: */
595
596               if (dir == RIGHT)
597                 {
598                   texture_draw(&cape_right[global_frame_counter % 2],
599                                base.x- scroll_x, base.y);
600                 }
601               else
602                 {
603                   texture_draw(&cape_left[global_frame_counter % 2],
604                                base.x- scroll_x, base.y);
605                 }
606             }
607
608
609           if (!got_coffee)
610             {
611               if (dir == RIGHT)
612                 {
613                   texture_draw(&tux_right[frame_], base.x- scroll_x, base.y);
614                 }
615               else
616                 {
617                   texture_draw(&tux_left[frame_], base.x- scroll_x, base.y);
618                 }
619             }
620           else
621             {
622               /* Tux got coffee! */
623
624               if (dir == RIGHT)
625                 {
626                   texture_draw(&firetux_right[frame_], base.x- scroll_x, base.y);
627                 }
628               else
629                 {
630                   texture_draw(&firetux_left[frame_], base.x- scroll_x, base.y);
631                 }
632             }
633         }
634       else
635         {
636           if (timer_started(&invincible_timer))
637             {
638               /* Draw cape: */
639               if (dir == RIGHT)
640                 {
641                   texture_draw(&bigcape_right[global_frame_counter % 2],
642                                base.x- scroll_x - 8, base.y);
643                 }
644               else
645                 {
646                   texture_draw(&bigcape_left[global_frame_counter % 2],
647                                base.x-scroll_x - 8, base.y);
648                 }
649             }
650
651           if (!got_coffee)
652             {
653               if (!duck)
654                 {
655                   if (!timer_started(&skidding_timer))
656                     {
657                       if (!jumping || base.ym > 0)
658                         {
659                           if (dir == RIGHT)
660                             {
661                               texture_draw(&bigtux_right[frame_],
662                                            base.x- scroll_x - 8, base.y);
663                             }
664                           else
665                             {
666                               texture_draw(&bigtux_left[frame_],
667                                            base.x- scroll_x - 8, base.y);
668                             }
669                         }
670                       else
671                         {
672                           if (dir == RIGHT)
673                             {
674                               texture_draw(&bigtux_right_jump,
675                                            base.x- scroll_x - 8, base.y);
676                             }
677                           else
678                             {
679                               texture_draw(&bigtux_left_jump,
680                                            base.x- scroll_x - 8, base.y);
681                             }
682                         }
683                     }
684                   else
685                     {
686                       if (dir == RIGHT)
687                         {
688                           texture_draw(&skidtux_right,
689                                        base.x- scroll_x - 8, base.y);
690                         }
691                       else
692                         {
693                           texture_draw(&skidtux_left,
694                                        base.x- scroll_x - 8, base.y);
695                         }
696                     }
697                 }
698               else
699                 {
700                   if (dir == RIGHT)
701                     {
702                       texture_draw(&ducktux_right, base.x- scroll_x - 8, base.y - 16);
703                     }
704                   else
705                     {
706                       texture_draw(&ducktux_left, base.x- scroll_x - 8, base.y - 16);
707                     }
708                 }
709             }
710           else
711             {
712               /* Tux has coffee! */
713
714               if (!duck)
715                 {
716                   if (!timer_started(&skidding_timer))
717                     {
718                       if (!jumping || base.ym > 0)
719                         {
720                           if (dir == RIGHT)
721                             {
722                               texture_draw(&bigfiretux_right[frame_],
723                                            base.x- scroll_x - 8, base.y);
724                             }
725                           else
726                             {
727                               texture_draw(&bigfiretux_left[frame_],
728                                            base.x- scroll_x - 8, base.y);
729                             }
730                         }
731                       else
732                         {
733                           if (dir == RIGHT)
734                             {
735                               texture_draw(&bigfiretux_right_jump,
736                                            base.x- scroll_x - 8, base.y);
737                             }
738                           else
739                             {
740                               texture_draw(&bigfiretux_left_jump,
741                                            base.x- scroll_x - 8, base.y);
742                             }
743                         }
744                     }
745                   else
746                     {
747                       if (dir == RIGHT)
748                         {
749                           texture_draw(&skidfiretux_right,
750                                        base.x- scroll_x - 8, base.y);
751                         }
752                       else
753                         {
754                           texture_draw(&skidfiretux_left,
755                                        base.x- scroll_x - 8, base.y);
756                         }
757                     }
758                 }
759               else
760                 {
761                   if (dir == RIGHT)
762                     {
763                       texture_draw(&duckfiretux_right, base.x- scroll_x - 8, base.y - 16);
764                     }
765                   else
766                     {
767                       texture_draw(&duckfiretux_left, base.x- scroll_x - 8, base.y - 16);
768                     }
769                 }
770             }
771         }
772     }
773 }
774
775 void
776 Player::collision(void* p_c_object, int c_object)
777 {
778   BadGuy* pbad_c = NULL;
779
780   switch (c_object)
781     {
782     case CO_BADGUY:
783       pbad_c = (BadGuy*) p_c_object;
784       /* Hurt the player if he just touched it: */
785
786       if (!pbad_c->dying && !dying &&
787           !timer_started(&safe_timer) &&
788           pbad_c->mode != HELD)
789         {
790           if (pbad_c->mode == FLAT  && input.fire != DOWN)
791             {
792               /* Kick: */
793
794               pbad_c->mode = KICK;
795               play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER);
796
797               if (base.x < pbad_c->base.x + (pbad_c->base.width/2))
798                 {
799                   pbad_c->dir = RIGHT;
800                   pbad_c->base.x = pbad_c->base.x + 16;
801                 }
802               else
803                 {
804                   pbad_c->dir = LEFT;
805                   pbad_c->base.x = pbad_c->base.x - 32;
806                 }
807
808               timer_start(&pbad_c->timer,5000);
809             }
810           else if (pbad_c->mode == FLAT && input.fire == DOWN)
811             {
812               pbad_c->mode = HELD;
813               pbad_c->base.y-=8;
814             }
815           else if (pbad_c->mode == KICK)
816             {
817               if (base.y < pbad_c->base.y - 16 &&
818                   timer_started(&pbad_c->timer))
819                 {
820                   /* Step on (stop being kicked) */
821
822                   pbad_c->mode = FLAT;
823                   play_sound(sounds[SND_STOMP], SOUND_CENTER_SPEAKER);
824                   timer_start(&pbad_c->timer, 10000);
825                 }
826               else
827                 {
828                   /* Hurt if you get hit by kicked laptop: */
829
830                   if (timer_started(&pbad_c->timer))
831                     {
832                       if (!timer_started(&invincible_timer))
833                         {
834                           kill(SHRINK);
835                         }
836                       else
837                         {
838                           pbad_c->dying = DYING_FALLING;
839                           play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
840                           add_score(pbad_c->base.x - scroll_x,
841                                     pbad_c->base.y,
842                                     25 * score_multiplier);
843                         }
844                     }
845                 }
846             }
847           else
848             {
849               if (!timer_started(&invincible_timer ))
850                 {
851                   kill(SHRINK);
852                 }
853               else
854                 {
855                   pbad_c->dying = DYING_FALLING;
856                   play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
857                   add_score(pbad_c->base.x - scroll_x,
858                             pbad_c->base.y,
859                             25 * score_multiplier);
860                 }
861             }
862           score_multiplier++;
863         }
864       break;
865     default:
866       break;
867     }
868
869 }
870
871 /* Kill Player! */
872
873 void
874 Player::kill(int mode)
875 {
876   base.ym = -5;
877
878   play_sound(sounds[SND_HURT], SOUND_CENTER_SPEAKER);
879
880   if (dir == RIGHT)
881     base.xm = -8;
882   else if (dir == LEFT)
883     base.xm = 8;
884
885   if (mode == SHRINK && size == BIG)
886     {
887       if (got_coffee)
888         got_coffee = false;
889
890       size = SMALL;
891       base.height = 32;
892
893       timer_start(&safe_timer,TUX_SAFE_TIME);
894     }
895   else
896     {
897       dying = DYING_SQUISHED;
898     }
899 }
900
901 void
902 Player::is_dying()
903 {
904   base.ym = base.ym + gravity;
905
906   /* He died :^( */
907
908   --lives;
909   remove_powerups();
910   dying = DYING_NOT;
911   
912   level_begin();
913
914 }
915
916 /* Remove Tux's power ups */
917 void
918 Player::remove_powerups()
919 {
920   got_coffee = false;
921   size = SMALL;
922   base.height = 32;
923 }
924
925 void
926 Player::keep_in_bounds()
927 {
928   /* Keep tux in bounds: */
929   if (base.x< 0)
930     base.x= 0;
931   else if(base.x< scroll_x)
932     base.x= scroll_x;
933   else if (base.x< 160 + scroll_x && scroll_x > 0 && debug_mode)
934     {
935       scroll_x = base.x- 160;
936       /*base.x+= 160;*/
937
938       if(scroll_x < 0)
939         scroll_x = 0;
940
941     }
942   else if (base.x> screen->w / 2 + scroll_x && scroll_x < ((current_level.width * 32) - screen->w))
943     {
944       /* Scroll the screen in past center: */
945
946       scroll_x = base.x- screen->w / 2;
947       /*base.x= 320 + scroll_x;*/
948
949       if (scroll_x > ((current_level.width * 32) - screen->w))
950         scroll_x = ((current_level.width * 32) - screen->w);
951     }
952   else if (base.x> 608 + scroll_x)
953     {
954       /* ... unless there's no more to scroll! */
955
956       /*base.x= 608 + scroll_x;*/
957     }
958
959   /* Keep in-bounds, vertically: */
960
961   if (base.y > screen->h)
962     {
963       kill(KILL);
964     }
965 }