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