Gameplay has been repaired a bit. A menu effect was added. OpenGL works without SDL_O...
[supertux.git] / src / player.c
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 "screen.h"
19
20 texture_type tux_life,
21 tux_right[3],  tux_left[3],
22 bigtux_right[3],  bigtux_left[3],
23 bigtux_right_jump,  bigtux_left_jump,
24 ducktux_right,  ducktux_left,
25 skidtux_right,  skidtux_left,
26 firetux_right[3],  firetux_left[3],
27 bigfiretux_right[3],  bigfiretux_left[3],
28 bigfiretux_right_jump,  bigfiretux_left_jump,
29 duckfiretux_right,  duckfiretux_left,
30 skidfiretux_right,  skidfiretux_left,
31 cape_right[2],  cape_left[2],
32 bigcape_right[2],  bigcape_left[2];
33
34 void player_init(player_type* pplayer)
35 {
36   pplayer->base.width = 32;
37   pplayer->base.height = 32;
38
39   pplayer->size = SMALL;
40   pplayer->got_coffee = NO;
41
42   pplayer->base.x = 0;
43   pplayer->base.y = 240;
44   pplayer->base.xm = 0;
45   pplayer->base.ym = 0;
46   pplayer->dir = RIGHT;
47   pplayer->duck = NO;
48
49   pplayer->dying = NO;
50   pplayer->jumping = NO;
51
52   pplayer->frame_main = 0;
53   pplayer->frame = 0;
54   pplayer->lives = 3;
55   pplayer->score = 0;
56   pplayer->distros = 0;
57
58   pplayer->input.down = UP;
59   pplayer->input.fire = UP;
60   pplayer->input.left = UP;
61   pplayer->input.old_fire = UP;
62   pplayer->input.right = UP;
63   pplayer->input.up = UP;
64
65   pplayer->keymap.jump = SDLK_UP;
66   pplayer->keymap.duck = SDLK_DOWN;
67   pplayer->keymap.left = SDLK_LEFT;
68   pplayer->keymap.right = SDLK_RIGHT;
69   pplayer->keymap.fire = SDLK_LCTRL;
70
71   timer_init(&pplayer->invincible_timer,YES);
72   timer_init(&pplayer->skidding_timer,YES);
73   timer_init(&pplayer->safe_timer,YES);
74   physic_init(&pplayer->hphysic);
75   physic_init(&pplayer->vphysic);
76 }
77
78 int player_key_event(player_type* pplayer, SDLKey key, int state)
79 {
80   if(key == pplayer->keymap.right)
81     {
82       pplayer->input.right = state;
83       return YES;
84     }
85   else if( key == pplayer->keymap.left)
86     {
87       pplayer->input.left = state;
88       return YES;
89     }
90   else if(key == pplayer->keymap.jump)
91     {
92       pplayer->input.up = state;
93       return YES;
94     }
95   else if(key == pplayer->keymap.duck)
96     {
97       pplayer->input.down = state;
98       return YES;
99     }
100   else if(key == pplayer->keymap.fire)
101     {
102       pplayer->input.fire = state;
103       return YES;
104     }
105   else
106     return NO;
107 }
108
109 void player_level_begin(player_type* pplayer)
110 {
111   pplayer->base.x = 0;
112   pplayer->base.y = 240;
113   pplayer->base.xm = 0;
114   pplayer->base.ym = 0;
115
116   pplayer->input.down = UP;
117   pplayer->input.fire = UP;
118   pplayer->input.left = UP;
119   pplayer->input.old_fire = UP;
120   pplayer->input.right = UP;
121   pplayer->input.up = UP;
122
123   timer_init(&pplayer->invincible_timer,YES);
124   timer_init(&pplayer->skidding_timer,YES);
125   timer_init(&pplayer->safe_timer,YES);
126 }
127
128 void player_action(player_type* pplayer)
129 {
130   /* --- HANDLE TUX! --- */
131
132   player_input(pplayer);
133
134   /* Move tux: */
135
136   pplayer->base.x += pplayer->base.xm * frame_ratio;
137   pplayer->base.y += pplayer->base.ym * frame_ratio;
138
139   player_keep_in_bounds(pplayer);
140
141   /* Land: */
142
143   if (!pplayer->dying)
144     {
145
146       /*if(physic_is_set(&pplayer->vphysic))
147         {
148           pplayer->base.ym = physic_get_velocity(&pplayer->vphysic);
149         }
150       else
151         {*/
152       if( /*!issolid( pplayer->base.x + 16,  pplayer->base.y + pplayer->base.height )*/ !player_on_ground(pplayer))
153         {
154           if(!physic_is_set(&pplayer->vphysic))
155             {
156               physic_set_state(&pplayer->vphysic,PH_VT);
157               physic_set_start_vy(&pplayer->vphysic,0.);
158               DEBUG_MSG("Ich bin jetzt ordentlich am Punkten"); 
159             }
160           pplayer->base.ym = physic_get_velocity(&pplayer->vphysic);
161         }
162       else
163         {
164            /* Land: */
165
166           if (pplayer->base.ym > 0)
167             {
168               pplayer->base.y = (int)(((int)(pplayer->base.y +1) / 32) * 32);
169               printf("%f",pplayer->base.y);
170               pplayer->base.ym = 0;
171             }
172           physic_init(&pplayer->vphysic);
173         }
174
175       while(issolid( pplayer->base.x + 16,  pplayer->base.y + pplayer->base.height) && !issolid( pplayer->base.x + 16,  pplayer->base.y))
176         {
177           --pplayer->base.y;
178         }
179       while(issolid( pplayer->base.x + 16,  pplayer->base.y + 1) && !issolid( pplayer->base.x + 16,  pplayer->base.y + pplayer->base.height))
180         {
181           ++pplayer->base.y;
182         }
183       while(issolid( pplayer->base.x - 1,  pplayer->base.y + 1) || issolid( pplayer->base.x - 1,  pplayer->base.y+pplayer->base.height))
184         {
185           ++pplayer->base.x;
186         }
187       while(issolid( pplayer->base.x + 32,  pplayer->base.y + 1) || issolid( pplayer->base.x + 32,  pplayer->base.y+pplayer->base.height))
188         {
189           --pplayer->base.x;
190         }
191
192       if(pplayer->base.ym <= 0)
193         {
194
195           if (isbrick(pplayer->base.x, pplayer->base.y) ||
196               isfullbox(pplayer->base.x, pplayer->base.y))
197             {
198               DEBUG_MSG("My sear");
199               trygrabdistro(pplayer->base.x, pplayer->base.y - 32,BOUNCE);
200               trybumpbadguy(pplayer->base.x, pplayer->base.y - 64);
201
202               if(pplayer->size == BIG)
203                 trybreakbrick(pplayer->base.x, pplayer->base.y);
204
205               bumpbrick(pplayer->base.x, pplayer->base.y);
206               tryemptybox(pplayer->base.x, pplayer->base.y);
207             }
208
209           if (isbrick(pplayer->base.x+ 31, pplayer->base.y) ||
210               isfullbox(pplayer->base.x+ 31, pplayer->base.y))
211             {
212               trygrabdistro(pplayer->base.x+ 31, pplayer->base.y - 32,BOUNCE);
213               trybumpbadguy(pplayer->base.x+ 31, pplayer->base.y - 64);
214
215               if(pplayer->size == BIG)
216                 trybreakbrick(pplayer->base.x+ 31, pplayer->base.y);
217
218               bumpbrick(pplayer->base.x+ 31, pplayer->base.y);
219               tryemptybox(pplayer->base.x+ 31, pplayer->base.y);
220             }
221
222
223           if(pplayer->size == SMALL)
224             {
225               /* Get a distro from a brick? */
226
227               if (shape(pplayer->base.x, pplayer->base.y) == 'x' ||
228                   shape(pplayer->base.x, pplayer->base.y) == 'y')
229                 {
230                   add_bouncy_distro((((int)pplayer->base.x)
231                                      / 32) * 32,
232                                     ((int)pplayer->base.y / 32) * 32);
233                   DEBUG_MSG("should work");
234                   if (counting_distros == NO)
235                     {
236                       counting_distros = YES;
237                       distro_counter = 100;
238                     }
239
240                   if (distro_counter <= 0)
241                     level_change(&current_level,pplayer->base.x,pplayer->base.y - 1, 'a');
242
243                   play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
244                   score = score + SCORE_DISTRO;
245                   distros++;
246                 }
247               else if (shape(pplayer->base.x+ 31, pplayer->base.y) == 'x' ||
248                        shape(pplayer->base.x+ 31, pplayer->base.y) == 'y')
249                 {
250                   add_bouncy_distro((((int)pplayer->base.x + 31)
251                                      / 32) * 32,
252                                     ((int)pplayer->base.y / 32) * 32);
253                   DEBUG_MSG("+31?");
254                   if (counting_distros == NO)
255                     {
256                       counting_distros = YES;
257                       distro_counter = 100;
258                     }
259
260                   if (distro_counter <= 0)
261                     level_change(&current_level,pplayer->base.x+ 31, pplayer->base.y, 'a');
262
263                   play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
264                   score = score + SCORE_DISTRO;
265                   distros++;
266                 }
267             }
268             }
269
270           player_grabdistros(pplayer);
271
272           /* FIXME: this code is COMPLETLY broken!!! */
273           /* if (issolid(pplayer->base.x, pplayer->base.y + 31) &&
274                !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y + 31))
275              {
276                while (issolid(pplayer->base.x, pplayer->base.y + 31))
277                  {
278                    if (pplayer->base.xm < 0)
279                      pplayer->base.x++;
280                    else if (pplayer->base.xm > 0)
281                      pplayer->base.x--;
282                  }
283
284                pplayer->base.xm = 0;
285              }*/
286
287           /*if (issolid(pplayer->base.x, pplayer->base.y) &&
288               !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y))
289             {
290               while (issolid(pplayer->base.x, (pplayer->base.y)))
291                 {
292                   if (pplayer->base.xm < 0)
293                     pplayer->base.x++;
294                   else if (pplayer->base.xm > 0)
295                     pplayer->base.x--;
296                 }
297
298               pplayer->base.xm = 0;
299             }*/
300
301           /*if (issolid(pplayer->base.x, pplayer->base.y + 31))
302             {
303               /* Set down properly: * /
304
305               int debug_int = 0;
306               while (issolid(pplayer->base.x, pplayer->base.y + 31))
307                 {
308                   ++debug_int;
309                   if(debug_int > 32)
310                     {
311                       DEBUG_MSG("FIXME - UNDER certain circumstances I'm hanging in a loop here!");
312                       /*the circumstances are:
313                       issolid() is true and base.ym == 0
314                       use of floating point varibles for base stuff* /
315                       break;
316                     }
317                   if (pplayer->base.ym < 0)
318                     pplayer->base.y++;
319                   else if (pplayer->base.ym > 0)
320                     pplayer->base.y--;
321                 }
322
323
324               /* Reset score multiplier (for multi-hits): */
325
326           if (pplayer->base.ym > 0)
327             score_multiplier = 1;
328
329
330           /* Stop jumping! * /
331
332           pplayer->base.ym = 0;
333           pplayer->jumping = NO;
334           pplayer->input.up = UP;
335           }
336           /* FIXME: this code is COMPLETLY broken!!! */
337           /*if (issolid(pplayer->base.x, pplayer->base.y) ||
338               (pplayer->size == BIG && !pplayer->duck &&
339                (issolid(pplayer->base.x, pplayer->base.y - 32))))
340             {*/
341           /*if (!issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y) &&
342               (pplayer->size == SMALL || pplayer->duck ||
343                !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y - 32)))* /
344
345           if (((!issolid(pplayer->base.x, pplayer->base.y- pplayer->base.ym * frame_ratio) && (issolid(pplayer->base.x, pplayer->base.y) || issolid(pplayer->base.x, pplayer->base.y+31))))
346           ||((!issolid(pplayer->base.x - pplayer->base.xm * frame_ratio, pplayer->base.y) && (issolid(pplayer->base.x, pplayer->base.y) || issolid(pplayer->base.x+32, pplayer->base.y)))))
347               /*(pplayer->size == SMALL || pplayer->duck ||
348                !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y - 32))* /
349             {
350               pplayer->base.y = pplayer->base.y- pplayer->base.ym * frame_ratio;
351               pplayer->base.ym = 0;
352             }
353
354           if (((issolid(pplayer->base.x, pplayer->base.y) || issolid(pplayer->base.x+32, pplayer->base.y)) &&  (!issolid(pplayer->base.x - pplayer->base.xm * frame_ratio, pplayer->base.y))
355               /*(pplayer->size == SMALL || pplayer->duck ||
356                !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y - 32))* /) || 
357           (!issolid(pplayer->base.x - pplayer->base.xm * frame_ratio, pplayer->base.y+pplayer->base.height) && (issolid(pplayer->base.x, pplayer->base.y+pplayer->base.height) || issolid(pplayer->base.x +32, pplayer->base.y+pplayer->base.height))))
358             {
359           pplayer->base.x = pplayer->base.x- pplayer->base.xm * frame_ratio;
360               pplayer->base.xm = 0;
361             }
362
363               if (pplayer->base.ym <= 0)
364                 {
365           if (isbrick(pplayer->base.x, pplayer->base.y) ||
366               isfullbox(pplayer->base.x, pplayer->base.y))
367             {
368               trygrabdistro(pplayer->base.x, pplayer->base.y - 32,BOUNCE);
369               trybumpbadguy(pplayer->base.x, pplayer->base.y - 64);
370               bumpbrick(pplayer->base.x, pplayer->base.y);
371               tryemptybox(pplayer->base.x, pplayer->base.y);
372             }
373
374           if (isbrick(pplayer->base.x+ 31, pplayer->base.y) ||
375               isfullbox(pplayer->base.x+ 31, pplayer->base.y))
376             {
377               trygrabdistro(pplayer->base.x+ 31, pplayer->base.y - 32,BOUNCE);
378               trybumpbadguy(pplayer->base.x+ 31, pplayer->base.y - 64);
379               bumpbrick(pplayer->base.x+ 31, pplayer->base.y);
380               tryemptybox(pplayer->base.x+ 31, pplayer->base.y);
381             }
382           /* Get a distro from a brick? * /
383
384           if (shape(pplayer->base.x, pplayer->base.y) == 'x' ||
385               shape(pplayer->base.x, pplayer->base.y) == 'y')
386             {
387               add_bouncy_distro(((pplayer->base.x+ 1)
388                                  / 32) * 32,
389                                 (int)(pplayer->base.y / 32) * 32);
390
391               if (counting_distros == NO)
392                 {
393                   counting_distros = YES;
394                   distro_counter = 100;
395                 }
396
397               if (distro_counter <= 0)
398                 level_change(&current_level,pplayer->base.x,pplayer->base.y, 'a');
399
400               play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
401               score = score + SCORE_DISTRO;
402               distros++;
403             }
404           else if (shape(pplayer->base.x+ 31, pplayer->base.y) == 'x' ||
405                    shape(pplayer->base.x+ 31, pplayer->base.y) == 'y')
406             {
407               add_bouncy_distro(((pplayer->base.x+ 1 + 31)
408                                  / 32) * 32,
409                                 (int)(pplayer->base.y / 32) * 32);
410
411               if (counting_distros == NO)
412                 {
413                   counting_distros = YES;
414                   distro_counter = 100;
415                 }
416
417               if (distro_counter <= 0)
418                 level_change(&current_level,pplayer->base.x+ 31, pplayer->base.y, 'a');
419
420               play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
421               score = score + SCORE_DISTRO;
422               distros++;
423             }
424
425           }
426           else
427           {
428           pplayer->base.ym = 0;
429           pplayer->jumping = NO;
430           timer_start(&pplayer->jump_timer,MAX_JUMP_TIME);
431           }
432           /*}*/
433           /* Bump into things: * /
434            
435           if (issolid(pplayer->base.x, pplayer->base.y) ||
436               (pplayer->size == BIG && !pplayer->duck &&
437                (issolid(pplayer->base.x, pplayer->base.y - 32))))
438             {
439            
440               if (!issolid(pplayer->base.x, pplayer->base.y - pplayer->base.ym) &&
441                   (pplayer->size == SMALL || pplayer->duck ||
442                    !issolid(pplayer->base.x, pplayer->base.y - 32 - pplayer->base.ym)))
443                 {
444                   if (pplayer->base.ym <= 0)
445                     {
446                       /* Jumping up? */
447           /* FIXME: this code is COMPLETLY broken!!! */
448           if (pplayer->size == BIG)
449             {
450               /* Break bricks and empty boxes: * /
451
452               if (!pplayer->duck)
453                 {
454                   if (isbrick(pplayer->base.x, pplayer->base.y - 32) ||
455                       isfullbox(pplayer->base.x, pplayer->base.y - 32))
456                     {
457                       trygrabdistro(pplayer->base.x, pplayer->base.y - 64, BOUNCE);
458                       trybumpbadguy(pplayer->base.x, pplayer->base.y - 96);
459
460                       if (isfullbox(pplayer->base.x, pplayer->base.y - 32))
461                         {
462                           bumpbrick(pplayer->base.x, pplayer->base.y - 32);
463                         }
464
465                       trybreakbrick(pplayer->base.x, pplayer->base.y - 32);
466                       tryemptybox(pplayer->base.x, pplayer->base.y - 32);
467                     }
468
469                   if (isbrick(pplayer->base.x+ 31, pplayer->base.y - 32) ||
470                       isfullbox(pplayer->base.x+ 31, pplayer->base.y - 32))
471                     {
472                       trygrabdistro(pplayer->base.x+ 31,
473                                     pplayer->base.y - 64,
474                                     BOUNCE);
475                       trybumpbadguy(pplayer->base.x+ 31,
476                                     pplayer->base.y - 96);
477
478                       if (isfullbox(pplayer->base.x+ 31, pplayer->base.y - 32))
479                         {
480                           bumpbrick(pplayer->base.x+ 31, pplayer->base.y - 32);
481                         }
482
483                       trybreakbrick(pplayer->base.x+ 31,
484                                     pplayer->base.y - 32);
485                       tryemptybox(pplayer->base.x+ 31,
486                                   pplayer->base.y - 32);
487                     }
488                 }
489               else /* ducking * /
490                 {
491                   if (isbrick(pplayer->base.x, pplayer->base.y) ||
492                       isfullbox(pplayer->base.x, pplayer->base.y))
493                     {
494                       trygrabdistro(pplayer->base.x, pplayer->base.y - 32,BOUNCE);
495                       trybumpbadguy(pplayer->base.x, pplayer->base.y - 64);
496                       if (isfullbox(pplayer->base.x, pplayer->base.y))
497                         bumpbrick(pplayer->base.x, pplayer->base.y);
498                       trybreakbrick(pplayer->base.x, pplayer->base.y);
499                       tryemptybox(pplayer->base.x, pplayer->base.y);
500                     }
501
502                   if (isbrick(pplayer->base.x+ 31, pplayer->base.y) ||
503                       isfullbox(pplayer->base.x+ 31, pplayer->base.y))
504                     {
505                       trygrabdistro(pplayer->base.x+ 31,
506                                     pplayer->base.y - 32,
507                                     BOUNCE);
508                       trybumpbadguy(pplayer->base.x+ 31,
509                                     pplayer->base.y - 64);
510                       if (isfullbox(pplayer->base.x+ 31, pplayer->base.y))
511                         bumpbrick(pplayer->base.x+ 31, pplayer->base.y);
512                       trybreakbrick(pplayer->base.x+ 31, pplayer->base.y);
513                       tryemptybox(pplayer->base.x+ 31, pplayer->base.y);
514                     }
515                 }
516               }
517               else
518               {
519               /* It's a brick and we're small, make the brick
520                  bounce, and grab any distros above it: *  /
521
522               if (isbrick(pplayer->base.x, pplayer->base.y) ||
523                   isfullbox(pplayer->base.x, pplayer->base.y))
524                 {
525                   trygrabdistro(pplayer->base.x, pplayer->base.y - 32,BOUNCE);
526                   trybumpbadguy(pplayer->base.x, pplayer->base.y - 64);
527                   bumpbrick(pplayer->base.x, pplayer->base.y);
528                   tryemptybox(pplayer->base.x, pplayer->base.y);
529                 }
530
531               if (isbrick(pplayer->base.x+ 31, pplayer->base.y) ||
532                   isfullbox(pplayer->base.x+ 31, pplayer->base.y))
533                 {
534                   trygrabdistro(pplayer->base.x+ 31, pplayer->base.y - 32,BOUNCE);
535                   trybumpbadguy(pplayer->base.x+ 31, pplayer->base.y - 64);
536                   bumpbrick(pplayer->base.x+ 31, pplayer->base.y);
537                   tryemptybox(pplayer->base.x+ 31, pplayer->base.y);
538                 }
539
540
541               /* Get a distro from a brick? * /
542
543               if (shape(pplayer->base.x, pplayer->base.y) == 'x' ||
544                   shape(pplayer->base.x, pplayer->base.y) == 'y')
545                 {
546                   add_bouncy_distro(((pplayer->base.x+ 1)
547                                      / 32) * 32,
548                                     (int)(pplayer->base.y / 32) * 32);
549
550                   if (counting_distros == NO)
551                     {
552                       counting_distros = YES;
553                       distro_counter = 100;
554                     }
555
556                   if (distro_counter <= 0)
557                     level_change(&current_level,pplayer->base.x,pplayer->base.y, 'a');
558
559                   play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
560                   score = score + SCORE_DISTRO;
561                   distros++;
562                 }
563               else if (shape(pplayer->base.x+ 31, pplayer->base.y) == 'x' ||
564                        shape(pplayer->base.x+ 31, pplayer->base.y) == 'y')
565                 {
566                   add_bouncy_distro(((pplayer->base.x+ 1 + 31)
567                                      / 32) * 32,
568                                     (int)(pplayer->base.y / 32) * 32);
569
570                   if (counting_distros == NO)
571                     {
572                       counting_distros = YES;
573                       distro_counter = 100;
574                     }
575
576                   if (distro_counter <= 0)
577                     level_change(&current_level,pplayer->base.x+ 31, pplayer->base.y, 'a');
578
579                   play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
580                   score = score + SCORE_DISTRO;
581                   distros++;
582                 }
583               }
584
585
586               /* Bump head: * /
587
588               pplayer->base.y = (int)(pplayer->base.y / 32) * 32 + 30;
589               }
590               else
591               {
592               /* Land on feet: * /
593
594               pplayer->base.y = (int)(pplayer->base.y / 32) * 32 - 32;
595               }
596
597               pplayer->base.ym = 0;
598               pplayer->jumping = NO;
599               timer_start(&pplayer->jump_timer,MAX_JUMP_TIME);
600               }*/
601             }
602     }
603
604
605   /*
606     player_grabdistros(pplayer);
607   */
608
609   /* Slow down horizontally: * /
610    
611   if (!pplayer->dying)
612     {
613       if (pplayer->input.right == UP && pplayer->input.left == UP)
614         {
615           if (isice(pplayer->base.x, pplayer->base.y + 32) ||
616               !issolid(pplayer->base.x, pplayer->base.y + 32))
617             {
618               /* Slowly on ice or in air: * /
619
620   if (pplayer->base.xm > 0)
621     pplayer->base.xm--;
622   else if (pplayer->base.xm < 0)
623     pplayer->base.xm++;
624   }
625   else
626   {
627     /* Quickly, otherwise: * /
628
629     pplayer->base.xm = pplayer->base.xm / 2;
630   }
631   }
632
633
634   /* Drop vertically: * /
635
636   if (!issolid(pplayer->base.x, pplayer->base.y + 32))
637   {
638     pplayer->base.ym = pplayer->base.ym + GRAVITY;
639
640     if (pplayer->base.ym > MAX_YM)
641       pplayer->base.ym = MAX_YM;
642   }
643   }
644
645
646   */
647   timer_check(&pplayer->safe_timer);
648
649
650   /* ---- DONE HANDLING TUX! --- */
651
652   /* Handle invincibility timer: */
653
654
655   if (current_music == HERRING_MUSIC && !timer_check(&pplayer->invincible_timer))
656     {
657       /*
658          no, we are no more invincible
659          or we were not in invincible mode
660          but are we in hurry ?
661        */
662
663
664       if (timer_get_left(&time_left) < TIME_WARNING)
665         {
666           /* yes, we are in hurry
667              stop the herring_song, prepare to play the correct
668              fast level_song !
669            */
670           current_music = HURRYUP_MUSIC;
671         }
672       else
673         {
674           current_music = LEVEL_MUSIC;
675         }
676
677       /* stop the old music if it's being played */
678       if (playing_music())
679         halt_music();
680     }
681
682   /* Handle skidding: */
683
684   timer_check(&pplayer->skidding_timer);
685
686   /* End of level? */
687
688   if (pplayer->base.x - scroll_x >= endpos && endpos != 0)
689     {
690       next_level = 1;
691     }
692
693 }
694
695 int player_on_ground(player_type *pplayer)
696 {
697   if( issolid(pplayer->base.x + pplayer->base.width / 2, pplayer->base.y + pplayer->base.height + 1) ||
698       issolid(pplayer->base.x + 1, pplayer->base.y + pplayer->base.height + 1) ||
699       issolid(pplayer->base.x + pplayer->base.width - 1, pplayer->base.y + pplayer->base.height + 1)  )
700     {
701       return YES;
702     }
703   else
704     {
705       return NO;
706     }
707 }
708
709 void player_handle_horizontal_input(player_type *pplayer, int dir)
710 {
711   if (pplayer->jumping == NO)
712     {
713       if ((dir ? (pplayer->base.xm < -SKID_XM) : (pplayer->base.xm > SKID_XM)) && !timer_started(&pplayer->skidding_timer) &&
714           pplayer->dir == !dir)
715         {
716           timer_start(&pplayer->skidding_timer, SKID_TIME);
717
718           play_sound(sounds[SND_SKID], SOUND_CENTER_SPEAKER);
719
720         }
721       pplayer->dir = dir;
722     }
723
724   if ((dir ? (pplayer->base.xm < 0) : (pplayer->base.xm > 0)) && !isice(pplayer->base.x, pplayer->base.y + 32) &&
725       !timer_started(&pplayer->skidding_timer))
726     {
727       pplayer->base.xm = 0;
728     }
729
730   if (!pplayer->duck)
731     {
732       if (pplayer->dir == dir)
733         {
734           /* Facing the direction we're jumping?  Go full-speed: */
735
736           if (pplayer->input.fire == UP)
737             {
738               pplayer->base.xm = pplayer->base.xm + ( dir ? WALK_SPEED : -WALK_SPEED) * frame_ratio;
739
740               if(dir)
741                 {
742                   if (pplayer->base.xm > MAX_WALK_XM)
743                     pplayer->base.xm = MAX_WALK_XM;
744                 }
745               else
746                 {
747                   if (pplayer->base.xm < -MAX_WALK_XM)
748                     pplayer->base.xm = -MAX_WALK_XM;
749                 }
750             }
751           else if ( pplayer->input.fire == DOWN)
752             {
753               pplayer->base.xm = pplayer->base.xm + ( dir ? RUN_SPEED : -RUN_SPEED) * frame_ratio;
754
755               if(dir)
756                 {
757                   if (pplayer->base.xm > MAX_RUN_XM)
758                     pplayer->base.xm = MAX_RUN_XM;
759                 }
760               else
761                 {
762                   if (pplayer->base.xm < -MAX_RUN_XM)
763                     pplayer->base.xm = -MAX_RUN_XM;
764                 }
765             }
766           else
767             {
768               /* Not facing the direction we're jumping?
769               Go half-speed: */
770
771               pplayer->base.xm = pplayer->base.xm + ( dir ? (WALK_SPEED / 2) : -(WALK_SPEED / 2)) * frame_ratio;
772
773               if(dir)
774                 {
775                   if (pplayer->base.xm > MAX_WALK_XM / 2)
776                     pplayer->base.xm = MAX_WALK_XM / 2;
777                 }
778               else
779                 {
780                   if (pplayer->base.xm < -MAX_WALK_XM / 2)
781                     pplayer->base.xm = -MAX_WALK_XM / 2;
782                 }
783             }
784         }
785
786     }
787 }
788
789 void player_handle_vertical_input(player_type *pplayer)
790 {
791   if(pplayer->input.up == DOWN)
792     {
793       if (player_on_ground(pplayer))
794         {
795           if(!physic_is_set(&pplayer->vphysic))
796             {
797               physic_set_state(&pplayer->vphysic,PH_VT);
798               physic_set_start_vy(&pplayer->vphysic,5.5);
799               --pplayer->base.y;
800               pplayer->jumping = YES;
801               if (pplayer->size == SMALL)
802                 play_sound(sounds[SND_JUMP], SOUND_CENTER_SPEAKER);
803               else
804                 play_sound(sounds[SND_BIGJUMP], SOUND_CENTER_SPEAKER);
805             }
806         }
807     }
808   else if(pplayer->input.up == UP && pplayer->jumping == YES)
809     {
810       /* Land: * /
811       DEBUG_MSG("Stop Jump");
812       pplayer->jumping = NO;
813
814       if (pplayer->base.ym > 0)
815         {
816           pplayer->base.y = (int)(pplayer->base.y / 32) * 32;
817           pplayer->base.ym = 0;
818         }
819       physic_init(&pplayer->vphysic);
820       }
821       else if(pplayer->input.up == UP)
822       {*/
823       if (issolid(pplayer->base.x + 16, pplayer->base.y + pplayer->base.height + 1))
824         {
825           physic_init(&pplayer->vphysic);
826           pplayer->jumping == NO;
827         }
828       else
829         {
830           pplayer->jumping = NO;
831           printf("%f",physic_get_velocity(&pplayer->vphysic));
832           if(physic_is_set(&pplayer->vphysic))
833             {
834             if(physic_get_velocity(&pplayer->vphysic) < 0.)
835             {
836                         physic_set_state(&pplayer->vphysic,PH_VT);
837                             DEBUG_MSG("DUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUDE");
838               physic_set_start_vy(&pplayer->vphysic,0);
839               }
840             }
841           else
842             {
843             DEBUG_MSG("CHUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUHHHHAAA");
844               if(!physic_is_set(&pplayer->vphysic))
845                 {
846                             DEBUG_MSG("CHUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUHHHHAAA");
847                   physic_set_state(&pplayer->vphysic,PH_VT);
848                 }
849             }
850         }
851     }
852
853   /* Taking off? * /
854
855   if (!issolid(pplayer->base.x, pplayer->base.y + 32) ||
856       pplayer->base.ym != 0)
857     {
858       /* If they're not on the ground, or are currently moving
859       vertically, don't jump! * /
860
861       pplayer->jumping = NO;
862       timer_stop(&pplayer->jump_timer);
863     }
864   else
865     {
866       /* Make sure we're not standing back up into a solid! * /
867
868       if (pplayer->size == SMALL || pplayer->duck == NO ||
869           !issolid(pplayer->base.x, pplayer->base.y))
870         {
871           pplayer->jumping = YES;
872
873           if (pplayer->size == SMALL)
874             play_sound(sounds[SND_JUMP], SOUND_CENTER_SPEAKER);
875           else
876             play_sound(sounds[SND_BIGJUMP], SOUND_CENTER_SPEAKER);
877         }
878     }*/
879
880   /* Keep jumping for a while: * /
881
882   if (timer_check(&pplayer->jump_timer))
883     {
884       pplayer->base.ym = pplayer->base.ym - JUMP_SPEED * frame_ratio;
885       if (pplayer->base.ym < -YM_FOR_JUMP)
886         pplayer->base.ym = pplayer->base.ym/*-YM_FOR_JUMP* /;
887     }*/
888 }
889
890 void player_input(player_type *pplayer)
891 {
892   /* Handle key and joystick state: */
893
894
895   if (pplayer->input.right == DOWN && pplayer->input.left == UP)
896     {
897       player_handle_horizontal_input(pplayer,RIGHT);
898     }
899   else if (pplayer->input.left == DOWN && pplayer->input.right == UP)
900     {
901       player_handle_horizontal_input(pplayer,LEFT);
902     }
903   else
904     {
905       if(pplayer->base.xm > 0)
906         pplayer->base.xm = (int)(pplayer->base.xm - frame_ratio);
907       else if(pplayer->base.xm < 0)
908         pplayer->base.xm = (int)(pplayer->base.xm + frame_ratio);
909     }
910
911   /* Jump/jumping? */
912
913   if ( pplayer->input.up == DOWN || (pplayer->input.up == UP && pplayer->jumping == YES))
914     {
915       player_handle_vertical_input(pplayer);
916     }
917
918   /* Shoot! */
919
920   if (pplayer->input.fire == DOWN && pplayer->input.old_fire == UP && pplayer->got_coffee)
921     {
922       add_bullet(pplayer->base.x, pplayer->base.y, pplayer->base.xm, pplayer->dir);
923     }
924
925
926   /* Duck! */
927
928   if (pplayer->input.down == DOWN)
929     {
930       if (pplayer->size == BIG)
931         pplayer->duck = YES;
932     }
933   else
934     {
935       if (pplayer->size == BIG && pplayer->duck == YES)
936         {
937           /* Make sure we're not standing back up into a solid! */
938
939           if (!issolid(pplayer->base.x + 16, pplayer->base.y - 16))
940             pplayer->duck = NO;
941         }
942       else
943         pplayer->duck = NO;
944     }
945
946   /* (Tux): */
947
948   if (pplayer->input.right == UP && pplayer->input.left == UP)
949     {
950       pplayer->frame_main = 1;
951       pplayer->frame = 1;
952     }
953   else
954     {
955       if ((pplayer->input.fire == DOWN && (frame % 2) == 0) ||
956           (frame % 4) == 0)
957         pplayer->frame_main = (pplayer->frame_main + 1) % 4;
958
959       pplayer->frame = pplayer->frame_main;
960
961       if (pplayer->frame == 3)
962         pplayer->frame = 1;
963     }
964
965 }
966
967 void player_grabdistros(player_type *pplayer)
968 {
969   /* Grab distros: */
970   if (!pplayer->dying)
971     {
972       trygrabdistro(pplayer->base.x, pplayer->base.y, NO_BOUNCE);
973       trygrabdistro(pplayer->base.x+ 31, pplayer->base.y, NO_BOUNCE);
974
975       trygrabdistro(pplayer->base.x, pplayer->base.y + pplayer->base.height, NO_BOUNCE);
976       trygrabdistro(pplayer->base.x+ 31, pplayer->base.y + pplayer->base.height, NO_BOUNCE);
977
978       if(pplayer->size == BIG)
979         {
980           trygrabdistro(pplayer->base.x, pplayer->base.y + pplayer->base.height / 2, NO_BOUNCE);
981           trygrabdistro(pplayer->base.x+ 31, pplayer->base.y + pplayer->base.height / 2, NO_BOUNCE);
982         }
983
984     }
985
986
987   /* Enough distros for a One-up? */
988
989   if (distros >= DISTROS_LIFEUP)
990     {
991       distros = distros - DISTROS_LIFEUP;
992       if(pplayer->lives < MAX_LIVES)
993         pplayer->lives++;
994       /*We want to hear the sound even, if MAX_LIVES is reached*/
995       play_sound(sounds[SND_LIFEUP], SOUND_CENTER_SPEAKER);
996     }
997 }
998
999 void player_draw(player_type* pplayer)
1000 {
1001   if (!timer_started(&pplayer->safe_timer) || (frame % 2) == 0)
1002     {
1003       if (pplayer->size == SMALL)
1004         {
1005           if (timer_started(&pplayer->invincible_timer))
1006             {
1007               /* Draw cape: */
1008
1009               if (pplayer->dir == RIGHT)
1010                 {
1011                   texture_draw(&cape_right[frame % 2],
1012                                pplayer->base.x- scroll_x, pplayer->base.y,
1013                                NO_UPDATE);
1014                 }
1015               else
1016                 {
1017                   texture_draw(&cape_left[frame % 2],
1018                                pplayer->base.x- scroll_x, pplayer->base.y,
1019                                NO_UPDATE);
1020                 }
1021             }
1022
1023
1024           if (!pplayer->got_coffee)
1025             {
1026               if (pplayer->dir == RIGHT)
1027                 {
1028                   texture_draw(&tux_right[pplayer->frame], pplayer->base.x- scroll_x, pplayer->base.y, NO_UPDATE);
1029                 }
1030               else
1031                 {
1032                   texture_draw(&tux_left[pplayer->frame], pplayer->base.x- scroll_x, pplayer->base.y, NO_UPDATE);
1033                 }
1034             }
1035           else
1036             {
1037               /* Tux got coffee! */
1038
1039               if (pplayer->dir == RIGHT)
1040                 {
1041                   texture_draw(&firetux_right[pplayer->frame], pplayer->base.x- scroll_x, pplayer->base.y, NO_UPDATE);
1042                 }
1043               else
1044                 {
1045                   texture_draw(&firetux_left[pplayer->frame], pplayer->base.x- scroll_x, pplayer->base.y, NO_UPDATE);
1046                 }
1047             }
1048         }
1049       else
1050         {
1051           if (timer_started(&pplayer->invincible_timer))
1052             {
1053               /* Draw cape: */
1054
1055               if (pplayer->dir == RIGHT)
1056                 {
1057                   texture_draw(&bigcape_right[frame % 2],
1058                                pplayer->base.x- scroll_x - 8, pplayer->base.y,
1059                                NO_UPDATE);
1060                 }
1061               else
1062                 {
1063                   texture_draw(&bigcape_left[frame % 2],
1064                                pplayer->base.x-scroll_x - 8, pplayer->base.y,
1065                                NO_UPDATE);
1066                 }
1067             }
1068
1069           if (!pplayer->got_coffee)
1070             {
1071               if (!pplayer->duck)
1072                 {
1073                   if (!timer_started(&pplayer->skidding_timer))
1074                     {
1075                       if (!pplayer->jumping || pplayer->base.ym > 0)
1076                         {
1077                           if (pplayer->dir == RIGHT)
1078                             {
1079                               texture_draw(&bigtux_right[pplayer->frame],
1080                                            pplayer->base.x- scroll_x - 8, pplayer->base.y,
1081                                            NO_UPDATE);
1082                             }
1083                           else
1084                             {
1085                               texture_draw(&bigtux_left[pplayer->frame],
1086                                            pplayer->base.x- scroll_x - 8, pplayer->base.y,
1087                                            NO_UPDATE);
1088                             }
1089                         }
1090                       else
1091                         {
1092                           if (pplayer->dir == RIGHT)
1093                             {
1094                               texture_draw(&bigtux_right_jump,
1095                                            pplayer->base.x- scroll_x - 8, pplayer->base.y,
1096                                            NO_UPDATE);
1097                             }
1098                           else
1099                             {
1100                               texture_draw(&bigtux_left_jump,
1101                                            pplayer->base.x- scroll_x - 8, pplayer->base.y,
1102                                            NO_UPDATE);
1103                             }
1104                         }
1105                     }
1106                   else
1107                     {
1108                       if (pplayer->dir == RIGHT)
1109                         {
1110                           texture_draw(&skidtux_right,
1111                                        pplayer->base.x- scroll_x - 8, pplayer->base.y,
1112                                        NO_UPDATE);
1113                         }
1114                       else
1115                         {
1116                           texture_draw(&skidtux_left,
1117                                        pplayer->base.x- scroll_x - 8, pplayer->base.y,
1118                                        NO_UPDATE);
1119                         }
1120                     }
1121                 }
1122               else
1123                 {
1124                   if (pplayer->dir == RIGHT)
1125                     {
1126                       texture_draw(&ducktux_right, pplayer->base.x- scroll_x - 8, pplayer->base.y,
1127                                    NO_UPDATE);
1128                     }
1129                   else
1130                     {
1131                       texture_draw(&ducktux_left, pplayer->base.x- scroll_x - 8, pplayer->base.y,
1132                                    NO_UPDATE);
1133                     }
1134                 }
1135             }
1136           else
1137             {
1138               /* Tux has coffee! */
1139
1140               if (!pplayer->duck)
1141                 {
1142                   if (!timer_started(&pplayer->skidding_timer))
1143                     {
1144                       if (!pplayer->jumping || pplayer->base.ym > 0)
1145                         {
1146                           if (pplayer->dir == RIGHT)
1147                             {
1148                               texture_draw(&bigfiretux_right[pplayer->frame],
1149                                            pplayer->base.x- scroll_x - 8, pplayer->base.y,
1150                                            NO_UPDATE);
1151                             }
1152                           else
1153                             {
1154                               texture_draw(&bigfiretux_left[pplayer->frame],
1155                                            pplayer->base.x- scroll_x - 8, pplayer->base.y,
1156                                            NO_UPDATE);
1157                             }
1158                         }
1159                       else
1160                         {
1161                           if (pplayer->dir == RIGHT)
1162                             {
1163                               texture_draw(&bigfiretux_right_jump,
1164                                            pplayer->base.x- scroll_x - 8, pplayer->base.y,
1165                                            NO_UPDATE);
1166                             }
1167                           else
1168                             {
1169                               texture_draw(&bigfiretux_left_jump,
1170                                            pplayer->base.x- scroll_x - 8, pplayer->base.y,
1171                                            NO_UPDATE);
1172                             }
1173                         }
1174                     }
1175                   else
1176                     {
1177                       if (pplayer->dir == RIGHT)
1178                         {
1179                           texture_draw(&skidfiretux_right,
1180                                        pplayer->base.x- scroll_x - 8, pplayer->base.y,
1181                                        NO_UPDATE);
1182                         }
1183                       else
1184                         {
1185                           texture_draw(&skidfiretux_left,
1186                                        pplayer->base.x- scroll_x - 8, pplayer->base.y,
1187                                        NO_UPDATE);
1188                         }
1189                     }
1190                 }
1191               else
1192                 {
1193                   if (pplayer->dir == RIGHT)
1194                     {
1195                       texture_draw(&duckfiretux_right, pplayer->base.x- scroll_x - 8, pplayer->base.y,
1196                                    NO_UPDATE);
1197                     }
1198                   else
1199                     {
1200                       texture_draw(&duckfiretux_left, pplayer->base.x- scroll_x - 8, pplayer->base.y,
1201                                    NO_UPDATE);
1202                     }
1203                 }
1204             }
1205         }
1206     }
1207 }
1208
1209 void player_collision(player_type* pplayer, void* p_c_object, int c_object)
1210 {
1211   bad_guy_type* pbad_c = NULL;
1212
1213   switch (c_object)
1214     {
1215     case CO_BADGUY:
1216       pbad_c = (bad_guy_type*) p_c_object;
1217       /* Hurt the player if he just touched it: */
1218
1219       if (!pbad_c->dying && !pplayer->dying &&
1220           !timer_started(&pplayer->safe_timer) &&
1221           pbad_c->mode != HELD)
1222         {
1223           if (pbad_c->mode == FLAT  && pplayer->input.fire != DOWN)
1224             {
1225               /* Kick: */
1226
1227               pbad_c->mode = KICK;
1228               play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER);
1229
1230               if (pplayer->base.x<= pbad_c->base.x)
1231                 {
1232                   pbad_c->dir = RIGHT;
1233                   pbad_c->base.x = pbad_c->base.x + 16;
1234                 }
1235               else
1236                 {
1237                   pbad_c->dir = LEFT;
1238                   pbad_c->base.x = pbad_c->base.x - 16;
1239                 }
1240
1241               timer_start(&pbad_c->timer,5000);
1242             }
1243           else if (pbad_c->mode == FLAT && pplayer->input.fire == DOWN)
1244             {
1245               pbad_c->mode = HELD;
1246               pbad_c->base.y-=8;
1247             }
1248           else if (pbad_c->mode == KICK)
1249             {
1250               if (pplayer->base.y < pbad_c->base.y - 16 &&
1251                   timer_started(&pbad_c->timer))
1252                 {
1253                   /* Step on (stop being kicked) */
1254
1255                   pbad_c->mode = FLAT;
1256                   play_sound(sounds[SND_STOMP], SOUND_CENTER_SPEAKER);
1257                   timer_start(&pbad_c->timer, 10000);
1258                 }
1259               else
1260                 {
1261                   /* Hurt if you get hit by kicked laptop: */
1262
1263                   if (timer_started(&pbad_c->timer))
1264                     {
1265                       if (!timer_started(&pplayer->invincible_timer))
1266                         {
1267                           player_kill(pplayer,SHRINK);
1268                         }
1269                       else
1270                         {
1271                           pbad_c->dying = FALLING;
1272                           pbad_c->base.ym = -8;
1273                           play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
1274                         }
1275                     }
1276                 }
1277             }
1278           else
1279             {
1280               if (!timer_started(&pplayer->invincible_timer ))
1281                 {
1282                   player_kill(pplayer,SHRINK);
1283                 }
1284               else
1285                 {
1286                   pbad_c->dying = FALLING;
1287                   pbad_c->base.ym = -8;
1288                   play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
1289                 }
1290             }
1291           score_multiplier++;
1292         }
1293       break;
1294     default:
1295       break;
1296     }
1297
1298 }
1299
1300 /* Kill Player! */
1301
1302 void player_kill(player_type* pplayer, int mode)
1303 {
1304   pplayer->base.ym = -5;
1305
1306   play_sound(sounds[SND_HURT], SOUND_CENTER_SPEAKER);
1307
1308   if (pplayer->dir == RIGHT)
1309     pplayer->base.xm = -8;
1310   else if (pplayer->dir == LEFT)
1311     pplayer->base.xm = 8;
1312
1313   if (mode == SHRINK && pplayer->size == BIG)
1314     {
1315       if (pplayer->got_coffee)
1316         pplayer->got_coffee = NO;
1317
1318       pplayer->size = SMALL;
1319       pplayer->base.height = 32;
1320
1321       timer_start(&pplayer->safe_timer,TUX_SAFE_TIME);
1322     }
1323   else
1324     {
1325       pplayer->dying = 1;
1326     }
1327 }
1328
1329 void player_dying(player_type *pplayer)
1330 {
1331   pplayer->base.ym = pplayer->base.ym + gravity;
1332
1333   /* He died :^( */
1334
1335   --pplayer->lives;
1336   player_remove_powerups(pplayer);
1337   pplayer->dying = NO;
1338
1339   player_level_begin(pplayer);
1340
1341 }
1342
1343 /* Remove Tux's power ups */
1344 void player_remove_powerups(player_type* pplayer)
1345 {
1346   pplayer->got_coffee = NO;
1347   pplayer->size = SMALL;
1348   pplayer->base.height = 32;
1349 }
1350
1351 void player_keep_in_bounds(player_type* pplayer)
1352 {
1353   /* Keep tux in bounds: */
1354   if (pplayer->base.x< 0)
1355     pplayer->base.x= 0;
1356   else if(pplayer->base.x< scroll_x)
1357     pplayer->base.x= scroll_x;
1358   else if (pplayer->base.x< 160 + scroll_x && scroll_x > 0 && debug_mode == YES)
1359     {
1360       scroll_x = pplayer->base.x- 160;
1361       /*pplayer->base.x+= 160;*/
1362
1363       if(scroll_x < 0)
1364         scroll_x = 0;
1365
1366     }
1367   else if (pplayer->base.x> screen->w / 2 + scroll_x && scroll_x < ((current_level.width * 32) - screen->w))
1368     {
1369       /* Scroll the screen in past center: */
1370
1371       scroll_x = pplayer->base.x- screen->w / 2;
1372       /*pplayer->base.x= 320 + scroll_x;*/
1373
1374       if (scroll_x > ((current_level.width * 32) - screen->w))
1375         scroll_x = ((current_level.width * 32) - screen->w);
1376     }
1377   else if (pplayer->base.x> 608 + scroll_x)
1378     {
1379       /* ... unless there's no more to scroll! */
1380
1381       /*pplayer->base.x= 608 + scroll_x;*/
1382     }
1383
1384   /* Keep in-bounds, vertically: */
1385
1386   if (pplayer->base.y < 0)
1387     pplayer->base.y = 0;
1388   else if (pplayer->base.y > screen->h)
1389     {
1390       player_kill(&tux,KILL);
1391     }
1392 }