- fixed bricktile
[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
177
178       if( !on_ground())
179         {
180           if(under_solid())
181             {
182               physic_set_state(&vphysic,PH_VT);
183               physic_set_start_vy(&vphysic,0);
184               jumped_in_solid = true;
185             }
186           else
187             {
188               if(!physic_is_set(&vphysic))
189                 {
190                   physic_set_state(&vphysic,PH_VT);
191                   physic_set_start_vy(&vphysic,0);
192                 }
193             }
194           base.ym = physic_get_velocity(&vphysic);
195
196         }
197       else
198         {
199
200           /* Land: */
201
202           if (base.ym > 0)
203             {
204               base.y = (int)(((int)base.y / 32) * 32);
205               base.ym = 0;
206             }
207
208           physic_init(&vphysic);
209
210           /* Reset score multiplier (for multi-hits): */
211
212           score_multiplier = 1;
213         }
214
215       if(jumped_in_solid)
216         {
217           if (isbrick(base.x, base.y) ||
218               isfullbox(base.x, base.y))
219             {
220               trygrabdistro(base.x, base.y - 32,BOUNCE);
221               trybumpbadguy(base.x, base.y - 64);
222
223               if(size == BIG)
224                 trybreakbrick(base.x, base.y);
225
226               bumpbrick(base.x, base.y);
227               tryemptybox(base.x, base.y, RIGHT);
228             }
229
230           if (isbrick(base.x+ 31, base.y) ||
231               isfullbox(base.x+ 31, base.y))
232             {
233               trygrabdistro(base.x+ 31, base.y - 32,BOUNCE);
234               trybumpbadguy(base.x+ 31, base.y - 64);
235
236               if(size == BIG)
237                 trybreakbrick(base.x+ 31, base.y);
238
239               bumpbrick(base.x+ 31, base.y);
240               tryemptybox(base.x+ 31, base.y, LEFT);
241             }
242
243
244           if(size == SMALL)
245             {
246               /* Get a distro from a brick? */
247               if (gettile(base.x, base.y)->brick ||
248                   gettile(base.x, base.y)->brick)
249                 {
250                   add_bouncy_distro((((int)base.x)
251                                      / 32) * 32,
252                                     ((int)base.y / 32) * 32);
253                   if (counting_distros == false)
254                     {
255                       counting_distros = true;
256                       distro_counter = 100;
257                     }
258
259                   if (distro_counter <= 0)
260                     level_change(&current_level,base.x,base.y - 1, TM_IA, 'a');
261                     
262                   play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
263                   score = score + SCORE_DISTRO;
264                   distros++;
265                 }
266               else if (gettile(base.x+ 31, base.y)->brick ||
267                        gettile(base.x+ 31, base.y)->brick)
268                 {
269                   add_bouncy_distro((((int)base.x + 31)
270                                      / 32) * 32,
271                                     ((int)base.y / 32) * 32);
272                   if (counting_distros == false)
273                     {
274                       counting_distros = true;
275                       distro_counter = 100;
276                     }
277
278                   if (distro_counter <= 0)
279                     level_change(&current_level,base.x+ 31, base.y, TM_IA, 'a');
280
281                   play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
282                   score = score + SCORE_DISTRO;
283                   distros++;
284                 }
285             }
286         }
287
288       grabdistros();
289
290       if (jumped_in_solid)
291         {
292           ++base.y;
293           ++old_base.y;
294           if(on_ground())
295             {
296               /* Make sure jumping is off. */
297               jumping = false;
298             }
299         }
300
301     }
302
303   timer_check(&safe_timer);
304
305
306   /* ---- DONE HANDLING TUX! --- */
307
308   /* Handle invincibility timer: */
309
310
311   if (get_current_music() == HERRING_MUSIC && !timer_check(&invincible_timer))
312     {
313       /*
314          no, we are no more invincible
315          or we were not in invincible mode
316          but are we in hurry ?
317        */
318
319
320       if (timer_get_left(&time_left) < TIME_WARNING)
321         {
322           /* yes, we are in hurry
323              stop the herring_song, prepare to play the correct
324              fast level_song !
325            */
326           set_current_music(HURRYUP_MUSIC);
327         }
328       else
329         {
330           set_current_music(LEVEL_MUSIC);
331         }
332
333       /* start playing it */
334       play_current_music();
335     }
336
337   /* Handle skidding: */
338
339   timer_check(&skidding_timer);
340
341   /* End of level? */
342
343   if (base.x >= endpos && endpos != 0)
344     {
345       next_level = 1;
346     }
347
348 }
349
350 bool
351 Player::on_ground()
352 {
353   return ( issolid(base.x + base.width / 2, base.y + base.height) ||
354            issolid(base.x + 1, base.y + base.height) ||
355            issolid(base.x + base.width - 1, base.y + base.height)  );
356 }
357
358 bool
359 Player::under_solid()
360 {
361   return ( issolid(base.x + base.width / 2, base.y) ||
362            issolid(base.x + 1, base.y) ||
363            issolid(base.x + base.width - 1, base.y)  );
364 }
365
366 void
367 Player::handle_horizontal_input(int newdir)
368 {
369   if ((newdir ? (base.xm < -SKID_XM) : (base.xm > SKID_XM)) && !timer_started(&skidding_timer) &&
370       dir == !newdir && on_ground())
371     {
372       timer_start(&skidding_timer, SKID_TIME);
373
374       play_sound(sounds[SND_SKID], SOUND_CENTER_SPEAKER);
375
376     }
377   dir = newdir;
378
379
380   if ((newdir ? (base.xm < 0) : (base.xm > 0)) && !isice(base.x, base.y + base.height) &&
381       !timer_started(&skidding_timer))
382     {
383       base.xm = 0;
384     }
385
386   if (!duck)
387     {
388       if (dir == newdir)
389         {
390           /* Facing the direction we're jumping?  Go full-speed: */
391
392           if (input.fire == UP)
393             {
394               base.xm = base.xm + ( newdir ? WALK_SPEED : -WALK_SPEED) * frame_ratio;
395
396               if(newdir)
397                 {
398                   if (base.xm > MAX_WALK_XM)
399                     base.xm = MAX_WALK_XM;
400                 }
401               else
402                 {
403                   if (base.xm < -MAX_WALK_XM)
404                     base.xm = -MAX_WALK_XM;
405                 }
406             }
407           else if ( input.fire == DOWN)
408             {
409               base.xm = base.xm + ( newdir ? RUN_SPEED : -RUN_SPEED) * frame_ratio;
410
411               if(newdir)
412                 {
413                   if (base.xm > MAX_RUN_XM)
414                     base.xm = MAX_RUN_XM;
415                 }
416               else
417                 {
418                   if (base.xm < -MAX_RUN_XM)
419                     base.xm = -MAX_RUN_XM;
420                 }
421             }
422           else
423             {
424               /* Not facing the direction we're jumping?
425                  Go half-speed: */
426
427               base.xm = base.xm + ( newdir ? (WALK_SPEED / 2) : -(WALK_SPEED / 2)) * frame_ratio;
428
429               if(newdir)
430                 {
431                   if (base.xm > MAX_WALK_XM / 2)
432                     base.xm = MAX_WALK_XM / 2;
433                 }
434               else
435                 {
436                   if (base.xm < -MAX_WALK_XM / 2)
437                     base.xm = -MAX_WALK_XM / 2;
438                 }
439             }
440         }
441
442     }
443 }
444
445 void
446 Player::handle_vertical_input()
447 {
448   if(input.up == DOWN)
449     {
450       if (on_ground())
451         {
452           if(!physic_is_set(&vphysic))
453             {
454               physic_set_state(&vphysic,PH_VT);
455               physic_set_start_vy(&vphysic,5.5);
456               --base.y;
457               jumping = true;
458               if (size == SMALL)
459                 play_sound(sounds[SND_JUMP], SOUND_CENTER_SPEAKER);
460               else
461                 play_sound(sounds[SND_BIGJUMP], SOUND_CENTER_SPEAKER);
462             }
463         }
464     }
465   else if(input.up == UP && jumping)
466     {
467       if (on_ground())
468         {
469           physic_init(&vphysic);
470           jumping = false;
471         }
472       else
473         {
474           jumping = false;
475           if(physic_is_set(&vphysic))
476             {
477               if(physic_get_velocity(&vphysic) < 0.)
478                 {
479                   physic_set_state(&vphysic,PH_VT);
480                   physic_set_start_vy(&vphysic,0);
481                 }
482             }
483           else
484             {
485               if(!physic_is_set(&vphysic))
486                 {
487                   physic_set_state(&vphysic,PH_VT);
488                 }
489             }
490         }
491     }
492 }
493
494 void
495 Player::handle_input()
496 {
497   /* Handle key and joystick state: */
498   if(duck == false)
499     {
500       if (input.right == DOWN && input.left == UP)
501         {
502           handle_horizontal_input(RIGHT);
503         }
504       else if (input.left == DOWN && input.right == UP)
505         {
506           handle_horizontal_input(LEFT);
507         }
508       else
509         {
510           if(base.xm > 0)
511             {
512               base.xm = (int)(base.xm - frame_ratio);
513               if(base.xm < 0)
514                 base.xm = 0;
515             }
516           else if(base.xm < 0)
517             {
518               base.xm = (int)(base.xm + frame_ratio);
519               if(base.xm > 0)
520                 base.xm = 0;
521             }
522         }
523     }
524
525   /* Jump/jumping? */
526
527   if ( input.up == DOWN || (input.up == UP && jumping))
528     {
529       handle_vertical_input();
530     }
531
532   /* Shoot! */
533
534   if (input.fire == DOWN && input.old_fire == UP && got_coffee)
535     {
536       add_bullet(base.x, base.y, base.xm, dir);
537     }
538
539
540   /* Duck! */
541
542   if (input.down == DOWN)
543     {
544       if (size == BIG && duck != true)
545         {
546           duck = true;
547           base.height = 32;
548           base.y += 32;
549         }
550     }
551   else
552     {
553       if (size == BIG && duck)
554         {
555           /* Make sure we're not standing back up into a solid! */
556           base.height = 64;
557           base.y -= 32;
558
559           if (!collision_object_map(&base) /*issolid(base.x + 16, base.y - 16)*/)
560             {
561               duck = false;
562               base.height = 64;
563               old_base.y -= 32;
564               old_base.height = 64;
565             }
566           else
567             {
568               base.height = 32;
569               base.y += 32;
570             }
571         }
572       else
573         {
574           duck = false;
575         }
576     }
577
578   /* (Tux): */
579
580   if(!timer_check(&frame_timer))
581     {
582       timer_start(&frame_timer,25);
583       if (input.right == UP && input.left == UP)
584         {
585           frame_main = 1;
586           frame_ = 1;
587         }
588       else
589         {
590           if ((input.fire == DOWN && (global_frame_counter % 2) == 0) ||
591               (global_frame_counter % 4) == 0)
592             frame_main = (frame_main + 1) % 4;
593
594           frame_ = frame_main;
595
596           if (frame_ == 3)
597             frame_ = 1;
598         }
599     }
600
601 }
602
603 void
604 Player::grabdistros()
605 {
606   /* Grab distros: */
607   if (!dying)
608     {
609       trygrabdistro(base.x, base.y, NO_BOUNCE);
610       trygrabdistro(base.x+ 31, base.y, NO_BOUNCE);
611
612       trygrabdistro(base.x, base.y + base.height, NO_BOUNCE);
613       trygrabdistro(base.x+ 31, base.y + base.height, NO_BOUNCE);
614
615       if(size == BIG)
616         {
617           trygrabdistro(base.x, base.y + base.height / 2, NO_BOUNCE);
618           trygrabdistro(base.x+ 31, base.y + base.height / 2, NO_BOUNCE);
619         }
620
621     }
622
623   /* Enough distros for a One-up? */
624   if (distros >= DISTROS_LIFEUP)
625     {
626       distros = distros - DISTROS_LIFEUP;
627       if(lives < MAX_LIVES)
628         lives++;
629       /*We want to hear the sound even, if MAX_LIVES is reached*/
630       play_sound(sounds[SND_LIFEUP], SOUND_CENTER_SPEAKER);
631     }
632 }
633
634 void
635 Player::draw()
636 {
637   if (!timer_started(&safe_timer) || (global_frame_counter % 2) == 0)
638     {
639       if (size == SMALL)
640         {
641           if (timer_started(&invincible_timer))
642             {
643               /* Draw cape: */
644
645               if (dir == RIGHT)
646                 {
647                   texture_draw(&cape_right[global_frame_counter % 2],
648                                base.x- scroll_x, base.y);
649                 }
650               else
651                 {
652                   texture_draw(&cape_left[global_frame_counter % 2],
653                                base.x- scroll_x, base.y);
654                 }
655             }
656
657
658           if (!got_coffee)
659             {
660               if (dir == RIGHT)
661                 {
662                   texture_draw(&tux_right[frame_], base.x- scroll_x, base.y);
663                 }
664               else
665                 {
666                   texture_draw(&tux_left[frame_], base.x- scroll_x, base.y);
667                 }
668             }
669           else
670             {
671               /* Tux got coffee! */
672
673               if (dir == RIGHT)
674                 {
675                   texture_draw(&firetux_right[frame_], base.x- scroll_x, base.y);
676                 }
677               else
678                 {
679                   texture_draw(&firetux_left[frame_], base.x- scroll_x, base.y);
680                 }
681             }
682         }
683       else
684         {
685           if (timer_started(&invincible_timer))
686             {
687               /* Draw cape: */
688               if (dir == RIGHT)
689                 {
690                   texture_draw(&bigcape_right[global_frame_counter % 2],
691                                base.x- scroll_x - 8, base.y);
692                 }
693               else
694                 {
695                   texture_draw(&bigcape_left[global_frame_counter % 2],
696                                base.x-scroll_x - 8, base.y);
697                 }
698             }
699
700           if (!got_coffee)
701             {
702               if (!duck)
703                 {
704                   if (!timer_started(&skidding_timer))
705                     {
706                       if (!jumping || base.ym > 0)
707                         {
708                           if (dir == RIGHT)
709                             {
710                               texture_draw(&bigtux_right[frame_],
711                                            base.x- scroll_x - 8, base.y);
712                             }
713                           else
714                             {
715                               texture_draw(&bigtux_left[frame_],
716                                            base.x- scroll_x - 8, base.y);
717                             }
718                         }
719                       else
720                         {
721                           if (dir == RIGHT)
722                             {
723                               texture_draw(&bigtux_right_jump,
724                                            base.x- scroll_x - 8, base.y);
725                             }
726                           else
727                             {
728                               texture_draw(&bigtux_left_jump,
729                                            base.x- scroll_x - 8, base.y);
730                             }
731                         }
732                     }
733                   else
734                     {
735                       if (dir == RIGHT)
736                         {
737                           texture_draw(&skidtux_right,
738                                        base.x- scroll_x - 8, base.y);
739                         }
740                       else
741                         {
742                           texture_draw(&skidtux_left,
743                                        base.x- scroll_x - 8, base.y);
744                         }
745                     }
746                 }
747               else
748                 {
749                   if (dir == RIGHT)
750                     {
751                       texture_draw(&ducktux_right, base.x- scroll_x - 8, base.y - 16);
752                     }
753                   else
754                     {
755                       texture_draw(&ducktux_left, base.x- scroll_x - 8, base.y - 16);
756                     }
757                 }
758             }
759           else
760             {
761               /* Tux has coffee! */
762
763               if (!duck)
764                 {
765                   if (!timer_started(&skidding_timer))
766                     {
767                       if (!jumping || base.ym > 0)
768                         {
769                           if (dir == RIGHT)
770                             {
771                               texture_draw(&bigfiretux_right[frame_],
772                                            base.x- scroll_x - 8, base.y);
773                             }
774                           else
775                             {
776                               texture_draw(&bigfiretux_left[frame_],
777                                            base.x- scroll_x - 8, base.y);
778                             }
779                         }
780                       else
781                         {
782                           if (dir == RIGHT)
783                             {
784                               texture_draw(&bigfiretux_right_jump,
785                                            base.x- scroll_x - 8, base.y);
786                             }
787                           else
788                             {
789                               texture_draw(&bigfiretux_left_jump,
790                                            base.x- scroll_x - 8, base.y);
791                             }
792                         }
793                     }
794                   else
795                     {
796                       if (dir == RIGHT)
797                         {
798                           texture_draw(&skidfiretux_right,
799                                        base.x- scroll_x - 8, base.y);
800                         }
801                       else
802                         {
803                           texture_draw(&skidfiretux_left,
804                                        base.x- scroll_x - 8, base.y);
805                         }
806                     }
807                 }
808               else
809                 {
810                   if (dir == RIGHT)
811                     {
812                       texture_draw(&duckfiretux_right, base.x- scroll_x - 8, base.y - 16);
813                     }
814                   else
815                     {
816                       texture_draw(&duckfiretux_left, base.x- scroll_x - 8, base.y - 16);
817                     }
818                 }
819             }
820         }
821     }
822 }
823
824 void
825 Player::collision(void* p_c_object, int c_object)
826 {
827   BadGuy* pbad_c = NULL;
828
829   switch (c_object)
830     {
831     case CO_BADGUY:
832       pbad_c = (BadGuy*) p_c_object;
833       /* Hurt the player if he just touched it: */
834
835       if (!pbad_c->dying && !dying &&
836           !timer_started(&safe_timer) &&
837           pbad_c->mode != HELD)
838         {
839           if (pbad_c->mode == FLAT  && input.fire != DOWN)
840             {
841               /* Kick: */
842
843               pbad_c->mode = KICK;
844               play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER);
845
846               if (base.x < pbad_c->base.x + (pbad_c->base.width/2))
847                 {
848                   pbad_c->dir = RIGHT;
849                   pbad_c->base.x = pbad_c->base.x + 16;
850                 }
851               else
852                 {
853                   pbad_c->dir = LEFT;
854                   pbad_c->base.x = pbad_c->base.x - 32;
855                 }
856
857               timer_start(&pbad_c->timer,5000);
858             }
859           else if (pbad_c->mode == FLAT && input.fire == DOWN)
860             {
861               pbad_c->mode = HELD;
862               pbad_c->base.y-=8;
863             }
864           else if (pbad_c->mode == KICK)
865             {
866               if (base.y < pbad_c->base.y - 16 &&
867                   timer_started(&pbad_c->timer))
868                 {
869                   /* Step on (stop being kicked) */
870
871                   pbad_c->mode = FLAT;
872                   play_sound(sounds[SND_STOMP], SOUND_CENTER_SPEAKER);
873                   timer_start(&pbad_c->timer, 10000);
874                 }
875               else
876                 {
877                   /* Hurt if you get hit by kicked laptop: */
878
879                   if (timer_started(&pbad_c->timer))
880                     {
881                       if (!timer_started(&invincible_timer))
882                         {
883                           kill(SHRINK);
884                         }
885                       else
886                         {
887                           pbad_c->dying = DYING_FALLING;
888                           play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
889                           add_score(pbad_c->base.x - scroll_x,
890                                     pbad_c->base.y,
891                                     25 * score_multiplier);
892                         }
893                     }
894                 }
895             }
896           else
897             {
898               if (!timer_started(&invincible_timer ))
899                 {
900                   kill(SHRINK);
901                 }
902               else
903                 {
904                   pbad_c->dying = DYING_FALLING;
905                   play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
906                   add_score(pbad_c->base.x - scroll_x,
907                             pbad_c->base.y,
908                             25 * score_multiplier);
909                 }
910             }
911           score_multiplier++;
912         }
913       break;
914     default:
915       break;
916     }
917
918 }
919
920 /* Kill Player! */
921
922 void
923 Player::kill(int mode)
924 {
925   base.ym = -5;
926
927   play_sound(sounds[SND_HURT], SOUND_CENTER_SPEAKER);
928
929   if (dir == RIGHT)
930     base.xm = -8;
931   else if (dir == LEFT)
932     base.xm = 8;
933
934   if (mode == SHRINK && size == BIG)
935     {
936       if (got_coffee)
937         got_coffee = false;
938
939       size = SMALL;
940       base.height = 32;
941
942       timer_start(&safe_timer,TUX_SAFE_TIME);
943     }
944   else
945     {
946       dying = DYING_SQUISHED;
947     }
948 }
949
950 void
951 Player::is_dying()
952 {
953   base.ym = base.ym + gravity;
954
955   /* He died :^( */
956
957   --lives;
958   remove_powerups();
959   dying = DYING_NOT;
960   
961   level_begin();
962
963 }
964
965 /* Remove Tux's power ups */
966 void
967 Player::remove_powerups()
968 {
969   got_coffee = false;
970   size = SMALL;
971   base.height = 32;
972 }
973
974 void
975 Player::keep_in_bounds()
976 {
977   /* Keep tux in bounds: */
978   if (base.x< 0)
979     base.x= 0;
980   else if(base.x< scroll_x)
981     base.x= scroll_x;
982   else if (base.x< 160 + scroll_x && scroll_x > 0 && debug_mode)
983     {
984       scroll_x = base.x- 160;
985       /*base.x+= 160;*/
986
987       if(scroll_x < 0)
988         scroll_x = 0;
989
990     }
991   else if (base.x> screen->w / 2 + scroll_x && scroll_x < ((current_level.width * 32) - screen->w))
992     {
993       /* Scroll the screen in past center: */
994
995       scroll_x = base.x- screen->w / 2;
996       /*base.x= 320 + scroll_x;*/
997
998       if (scroll_x > ((current_level.width * 32) - screen->w))
999         scroll_x = ((current_level.width * 32) - screen->w);
1000     }
1001   else if (base.x> 608 + scroll_x)
1002     {
1003       /* ... unless there's no more to scroll! */
1004
1005       /*base.x= 608 + scroll_x;*/
1006     }
1007
1008   /* Keep in-bounds, vertically: */
1009
1010   if (base.y > screen->h)
1011     {
1012       kill(KILL);
1013     }
1014 }