- introduced new function wait_for_event
[supertux.git] / src / badguy.cpp
1 //
2 // C Implementation: badguy
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 #include <math.h>
13
14 #include "globals.h"
15 #include "defines.h"
16 #include "badguy.h"
17 #include "scene.h"
18 #include "screen.h"
19
20 texture_type img_bsod_squished_left;
21 texture_type img_bsod_squished_right;
22 texture_type img_bsod_falling_left;
23 texture_type img_bsod_falling_right;
24 texture_type img_laptop_flat_left;
25 texture_type img_laptop_flat_right;
26 texture_type img_laptop_falling_left;
27 texture_type img_laptop_falling_right;
28 texture_type img_bsod_left[4];
29 texture_type img_bsod_right[4];
30 texture_type img_laptop_left[3];
31 texture_type img_laptop_right[3];
32 texture_type img_money_left[2];
33 texture_type img_money_right[2];
34 texture_type img_mrbomb_left[4];
35 texture_type img_mrbomb_right[4];
36 texture_type img_mrbomb_ticking_left;
37 texture_type img_mrbomb_ticking_right;
38 texture_type img_mrbomb_explosion;
39 texture_type img_stalactite;
40 texture_type img_stalactite_broken;
41 texture_type img_flame[2];
42
43 BadGuyKind  badguykind_from_string(const std::string& str)
44 {
45   if (str == "money")
46     return BAD_MONEY;
47   else if (str == "laptop")
48     return BAD_LAPTOP;
49   else if (str == "bsod")
50     return BAD_BSOD;
51   else if (str == "mrbomb")
52     return BAD_MRBOMB;
53   else if (str == "stalactite")
54     return BAD_STALACTITE;
55   else if (str == "flame")
56     return BAD_FLAME;
57   else
58     {
59       printf("Couldn't convert badguy: %s\n", str.c_str());
60       return BAD_BSOD;
61     }
62 }
63
64 std::string badguykind_to_string(BadGuyKind kind)
65 {
66   switch(kind)
67     {
68     case BAD_MONEY:
69       return "money";
70       break;
71     case BAD_LAPTOP:
72       return "laptop";
73       break;
74     case BAD_BSOD:
75       return "bsod";
76       break;
77     case BAD_MRBOMB:
78       return "mrbomb";
79       break;
80     case BAD_STALACTITE:
81       return "stalactite";
82       break;
83     case BAD_FLAME:
84       return "flame";
85       break;
86     default:
87       return "bsod";
88     }
89 }
90
91 void
92 BadGuy::init(float x, float y, BadGuyKind kind_)
93 {
94   base.x   = x;
95   base.y   = y;    
96   base.width  = 32;
97   base.height = 32;
98   mode     = NORMAL;
99   dying    = DYING_NOT;
100   kind     = kind_;
101   base.xm  = -1.3;
102   base.ym  = 0;
103   old_base = base;
104   dir      = LEFT;
105   seen     = false;
106   timer_init(&timer, true);
107   physic_init(&physic);
108
109   if(kind == BAD_BOMB) {
110     timer_start(&timer, 1000);
111     mode = BOMB_TICKING;
112     // hack so that the bomb doesn't hurt until it expldes...
113     dying = DYING_SQUISHED;
114   } else if(kind == BAD_FLAME) {
115     base.ym = 0; // we misuse base.ym as angle for the flame
116   } else if(kind == BAD_MONEY) {
117     base.ym = 4.8;
118   }
119 }
120
121 void BadGuy::action_bsod()
122 {
123   /* --- BLUE SCREEN OF DEATH MONSTER: --- */
124
125   /* Move left/right: */
126   if (dying == DYING_NOT || dying == DYING_FALLING)
127     {
128       base.x += base.xm * frame_ratio;
129     }
130
131   /* Move vertically: */
132   base.y += base.ym * frame_ratio;
133
134   if (dying != DYING_FALLING)
135     collision_swept_object_map(&old_base,&base);
136                 
137   if (!dying)
138     check_horizontal_bump();
139
140   fall(true);
141
142   // Handle dying timer:
143   if (dying == DYING_SQUISHED && !timer_check(&timer))       
144     {
145       /* Remove it if time's up: */
146       remove_me();
147       return;
148     }
149 }
150
151 void BadGuy::action_laptop()
152 {
153   /* Move left/right: */
154   if (mode == NORMAL || mode == KICK)
155     {
156       if (dying == DYING_NOT ||
157           dying == DYING_FALLING)
158         {
159           base.x += base.xm * frame_ratio;
160         }
161     }
162   else if (mode == HELD)
163     { /* FIXME: The pbad object shouldn't know about pplayer objects. */
164       /* If we're holding the laptop */
165       dir=tux.dir;
166       if(dir==RIGHT)
167         {
168           base.x = tux.base.x + 16;
169           base.y = tux.base.y + tux.base.height/1.5 - base.height;
170         }
171       else /* facing left */
172         {
173           base.x = tux.base.x - 16;
174           base.y = tux.base.y + tux.base.height/1.5 - base.height;
175         }
176       if(collision_object_map(&base))
177         {
178           base.x = tux.base.x;
179           base.y = tux.base.y + tux.base.height/1.5 - base.height;
180         }
181
182       if(tux.input.fire != DOWN) /* SHOOT! */
183         {
184           if(dir == LEFT)
185             base.x -= 24;
186           else
187             base.x += 24;
188
189           mode=KICK;
190           base.xm = 8;
191           base.ym = 8;
192           play_sound(sounds[SND_KICK],SOUND_CENTER_SPEAKER);
193         }
194     }
195
196
197   /* Move vertically: */
198   if(mode != HELD)
199     base.y = base.y + base.ym * frame_ratio;
200
201   if (dying != DYING_FALLING)
202     collision_swept_object_map(&old_base,&base);
203   /* Bump into things horizontally: */
204
205   if (!dying)
206     {
207       int changed = dir;
208       check_horizontal_bump();
209       if(mode == KICK && changed != dir)
210         {
211           /* handle stereo sound (number 10 should be tweaked...)*/
212           if (base.x < scroll_x + screen->w/2 - 10)
213             play_sound(sounds[SND_RICOCHET], SOUND_LEFT_SPEAKER);
214           else if (base.x > scroll_x + screen->w/2 + 10)
215             play_sound(sounds[SND_RICOCHET], SOUND_RIGHT_SPEAKER);
216           else
217             play_sound(sounds[SND_RICOCHET], SOUND_CENTER_SPEAKER);
218         }
219     }
220
221   fall();
222
223   /* Handle mode timer: */
224   if (mode == FLAT)
225     {
226       if(!timer_check(&timer))
227         {
228           mode = NORMAL;
229           base.xm = (dir == LEFT) ? -1.3 : 1.3;
230         }
231     }
232 }
233
234 void BadGuy::check_horizontal_bump(bool checkcliff)
235 {
236     if (dir == LEFT && issolid( base.x, (int) base.y + 16))
237     {
238         dir = RIGHT;
239         base.xm = -base.xm;
240         return;
241     }
242     if (dir == RIGHT && issolid( base.x + base.width, (int) base.y + 16))
243     {
244         dir = LEFT;
245         base.xm = -base.xm;
246         return;
247     }
248
249     // don't check for cliffs when we're falling
250     if(!checkcliff)
251         return;
252     if(!issolid(base.x + base.width/2, base.y + base.height + 16))
253         return;
254     
255     if(dir == LEFT && !issolid(base.x, (int) base.y + base.height + 16))
256     {
257         printf("Cliffcol left\n");
258         dir = RIGHT;
259         base.xm = -base.xm;
260         return;
261     }
262     if(dir == RIGHT && !issolid(base.x + base.width,
263                 (int) base.y + base.height + 16))
264     {
265         printf("Cliffcol right\n");
266         dir = LEFT;
267         base.xm = -base.xm;
268         return;
269     }
270 }
271
272 void BadGuy::fall(bool dojump)
273 {
274   /* Fall if we get off the ground: */
275   if (dying != DYING_FALLING)
276     {
277       if (!issolid(base.x+base.width/2, base.y + base.height))
278         {
279           if(!physic_is_set(&physic))
280             {
281               physic_set_state(&physic,PH_VT);
282               physic_set_start_vy(&physic, dojump ? 2. : 0.);
283             }
284
285           base.ym = physic_get_velocity(&physic);
286         }
287       else
288         {
289           /* Land: */
290           if (base.ym > 0)
291             {
292               base.y = int((base.y + base.height)/32) * 32 - base.height;
293               base.ym = 0;
294             }
295           physic_init(&physic);
296         }
297     }
298   else
299     {
300       if(!physic_is_set(&physic))
301         {                                                
302           physic_set_state(&physic,PH_VT);
303           physic_set_start_vy(&physic,0.);
304         }
305       base.ym = physic_get_velocity(&physic);
306     }
307
308   // BadGuy fall below the ground
309   if (base.y > screen->h) {
310     remove_me();
311     return;
312   }
313 }
314
315 void BadGuy::remove_me()
316 {
317   std::vector<BadGuy>::iterator i;
318   for(i = bad_guys.begin(); i != bad_guys.end(); ++i) {
319     if( & (*i) == this) {
320       bad_guys.erase(i);
321       return;
322     }
323   }
324 }
325
326 void BadGuy::action_money()
327 {
328   /* Move vertically: */
329   base.y = base.y + base.ym * frame_ratio;
330
331   if (dying != DYING_FALLING)
332     collision_swept_object_map(&old_base,&base);
333
334   if (base.y > screen->h) {
335     remove_me();
336     return;
337   }
338
339   if(physic_get_state(&physic) == -1)
340     {
341       physic_set_state(&physic,PH_VT);
342       physic_set_start_vy(&physic,0.);
343     }
344
345   if (dying != DYING_FALLING)
346     {
347       
348       if(issolid(base.x, base.y + 32))
349         {
350           physic_set_state(&physic,PH_VT);
351           physic_set_start_vy(&physic,6.);
352           base.ym = physic_get_velocity(&physic);
353           mode = MONEY_JUMP;
354         }
355       else
356         {
357           base.ym = physic_get_velocity(&physic);
358           mode = NORMAL;
359         }
360     }
361   else
362     {
363       if(!physic_is_set(&physic))
364         {
365           physic_set_state(&physic,PH_VT);
366           physic_set_start_vy(&physic,0.);
367         }
368       base.ym = physic_get_velocity(&physic);
369     } 
370 }
371
372 void BadGuy::action_mrbomb()
373 {
374   if(mode == NORMAL) {
375     base.x += base.xm * frame_ratio;
376   }
377
378   /* Move vertically: */
379   base.y += base.ym * frame_ratio;
380
381   if (dying != DYING_FALLING)
382     collision_swept_object_map(&old_base,&base);
383
384   check_horizontal_bump(true);
385   fall();
386 }
387
388 void BadGuy::action_bomb()
389 {
390   // eventually fall down
391   base.y += base.ym * frame_ratio;
392   collision_swept_object_map(&old_base,&base);
393   fall();
394
395   if(!timer_check(&timer)) {
396     if(mode == BOMB_TICKING) {
397       mode = BOMB_EXPLODE;
398       dying = DYING_NOT; // now the bomb hurts
399       timer_start(&timer, 1000);
400       // explosion image has different size
401       base.x -= (img_mrbomb_explosion.w - base.width) / 2;
402       base.y -= img_mrbomb_explosion.h - base.height;
403       base.width = img_mrbomb_explosion.w;
404       base.height = img_mrbomb_explosion.h;
405       old_base = base;
406     } else if(mode == BOMB_EXPLODE) {
407       remove_me();
408       return;
409     }
410   }
411 }
412
413 void BadGuy::action_stalactite()
414 {
415   if(mode == NORMAL) {
416     static const int range = 40;
417     // start shaking when tux is below the stalactite and at least 40 pixels
418     // near
419     if(tux.base.x + 32 > base.x - range && tux.base.x < base.x + 32 + range
420             && tux.base.y + tux.base.height > base.y) {
421       timer_start(&timer, 800);
422       mode = STALACTITE_SHAKING;
423     }
424   } if(mode == STALACTITE_SHAKING) {
425     base.x = old_base.x + (rand() % 6) - 3; // TODO this could be done nicer...
426     if(!timer_check(&timer)) {
427       mode = STALACTITE_FALL;
428     }
429   } else if(mode == STALACTITE_FALL) {
430     base.y += base.ym * frame_ratio;
431     fall();
432     /* Destroy if collides land */
433     if(issolid(base.x+16, base.y+32))
434     {
435       timer_start(&timer, 3000);
436       dying = DYING_SQUISHED;
437       mode = FLAT;
438     }
439   } else if(mode == FLAT) {
440     if(!timer_check(&timer)) {
441       remove_me();
442     }
443   }
444 }
445
446 void
447 BadGuy::action_flame()
448 {
449     static const float radius = 100;
450     static const float speed = 0.02;
451     base.x = old_base.x + cos(base.ym) * radius;
452     base.y = old_base.y + sin(base.ym) * radius;
453
454     base.ym = fmodf(base.ym + frame_ratio * speed, 2*M_PI);
455 }
456
457 void
458 BadGuy::action()
459 {
460   // Remove if it's far off the screen:
461   if (base.x < scroll_x - OFFSCREEN_DISTANCE)
462     {
463       remove_me();                                                
464       return;
465     }
466
467   // Once it's on screen, it's activated!
468   if (base.x <= scroll_x + screen->w + OFFSCREEN_DISTANCE)
469     seen = true;
470
471   if(!seen)
472     return;
473
474   switch (kind)
475     {
476     case BAD_BSOD:
477       action_bsod();
478       break;
479
480     case BAD_LAPTOP:
481       action_laptop();
482       break;
483   
484     case BAD_MONEY:
485       action_money();
486       break;
487
488     case BAD_MRBOMB:
489       action_mrbomb();
490       break;
491     
492     case BAD_BOMB:
493       action_bomb();
494       break;
495
496     case BAD_STALACTITE:
497       action_stalactite();
498       break;
499
500     case BAD_FLAME:
501       action_flame();
502       break;
503     }
504 }
505
506 void
507 BadGuy::draw_bsod()
508 {
509   texture_type* texture = 0;
510   
511   if(dying == DYING_NOT) {
512     size_t frame = (global_frame_counter / 5) % 4;
513     texture = (dir == LEFT) ? &img_bsod_left[frame] : &img_bsod_right[frame];
514   } else if(dying == DYING_FALLING) {
515     texture = (dir == LEFT) ? &img_bsod_falling_left : &img_bsod_falling_right;
516   } else if(dying == DYING_SQUISHED) {
517     texture = (dir == LEFT) 
518         ? &img_bsod_squished_left : &img_bsod_squished_right;
519   }
520   
521   texture_draw(texture, base.x - scroll_x, base.y);
522 }
523
524 void
525 BadGuy::draw_laptop()
526 {
527   texture_type* texture;
528   size_t frame = (global_frame_counter / 5) % 3;
529   
530   if(dying == DYING_NOT) {
531     if(mode == NORMAL) {
532       if(dir == LEFT)
533         texture = &img_laptop_left[frame];
534       else
535         texture = &img_laptop_right[frame];
536     } else {
537       texture = (dir == LEFT) ? &img_laptop_flat_left : &img_laptop_flat_right;
538     }
539   } else {
540     texture = (dir == LEFT) 
541         ? &img_laptop_falling_left : &img_laptop_falling_right;
542   }
543
544   texture_draw(texture, base.x - scroll_x, base.y);
545 }
546
547 void
548 BadGuy::draw_money()
549 {
550   texture_type* texture;
551   size_t frame = (mode == NORMAL) ? 0 : 1;
552
553   if(tux.base.x + tux.base.width < base.x) {
554     texture = &img_money_left[frame];
555   } else {
556     texture = &img_money_right[frame];
557   }
558
559   texture_draw(texture, base.x - scroll_x, base.y);
560 }
561   
562 void
563 BadGuy::draw_mrbomb()
564 {
565   texture_type* texture;
566   size_t frame = (global_frame_counter/5) % 4;
567
568   if(dir == LEFT)
569     texture = &img_mrbomb_left[frame];
570   else
571     texture = &img_mrbomb_right[frame];
572
573   texture_draw(texture, base.x - scroll_x, base.y);
574 }
575
576 void
577 BadGuy::draw_bomb()
578 {
579   texture_type* texture;
580
581   // TODO add real bomb graphics
582   if(mode == BOMB_TICKING) {
583     texture = (dir == LEFT) 
584         ? &img_mrbomb_ticking_left : &img_mrbomb_ticking_right;
585   } else {
586     texture = &img_mrbomb_explosion;
587   }
588   
589   texture_draw(texture, base.x - scroll_x, base.y);
590 }
591
592 void
593 BadGuy::draw_stalactite()
594 {
595   texture_type* texture;
596   if(mode != FLAT)
597     texture = &img_stalactite;
598   else
599     texture = &img_stalactite_broken;
600
601   texture_draw(texture, base.x - scroll_x, base.y);
602 }
603
604 void
605 BadGuy::draw_flame()
606 {
607   size_t frame = (global_frame_counter / 10) % 2;
608   texture_type* texture = &img_flame[frame];
609
610   texture_draw(texture, base.x - scroll_x, base.y);
611 }
612
613 void
614 BadGuy::draw()
615 {
616   // Don't try to draw stuff that is outside of the screen
617   if (base.x <= scroll_x - base.width || base.x >= scroll_x + screen->w)
618     return;
619       
620   switch (kind)
621     {
622     case BAD_BSOD:
623       draw_bsod();
624       break;
625
626     case BAD_LAPTOP:
627       draw_laptop();
628       break;
629
630     case BAD_MONEY:
631       draw_money();
632       break;
633
634     case BAD_MRBOMB:
635       draw_mrbomb();
636       break;
637
638     case BAD_BOMB:
639       draw_bomb();
640       break;
641
642     case BAD_STALACTITE:
643       draw_stalactite();
644       break;
645
646     case BAD_FLAME:
647       draw_flame();
648       break;
649
650     }
651 }
652
653 void
654 BadGuy::bump()
655 {
656   if(kind == BAD_BSOD || kind == BAD_LAPTOP || kind == BAD_BOMB) {
657     dying = DYING_FALLING;
658     base.ym = -8;
659     play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
660   }
661 }
662
663 void
664 BadGuy::make_player_jump(Player* player)
665 {
666     physic_set_state(&player->vphysic,PH_VT);
667     physic_set_start_vy(&player->vphysic, 2.);
668     player->base.y = base.y - player->base.height - 2;
669 }
670
671 void
672 BadGuy::squich(Player* player)
673 {
674   if(kind == BAD_MRBOMB) {
675       // mrbomb transforms into a bomb now
676       add_bad_guy(base.x, base.y, BAD_BOMB);
677       
678       make_player_jump(player);
679       add_score(base.x - scroll_x, base.y, 50 * score_multiplier);
680       play_sound(sounds[SND_SQUISH], SOUND_CENTER_SPEAKER);
681       score_multiplier++;
682       
683       remove_me();
684       return;
685
686   } else if(kind == BAD_BSOD) {
687       make_player_jump(player);
688
689       add_score(base.x - scroll_x, base.y, 50 * score_multiplier);
690       play_sound(sounds[SND_SQUISH], SOUND_CENTER_SPEAKER);
691       score_multiplier++;
692
693       dying = DYING_SQUISHED;
694       timer_start(&timer, 2000);
695       base.y += base.height - img_bsod_squished_left.h;
696       base.height = img_bsod_squished_left.h;
697       base.xm = base.ym = 0;
698       old_base = base;
699       return;
700       
701   } else if (kind == BAD_LAPTOP) {
702       if (mode == NORMAL || mode == KICK)
703       {
704           /* Flatten! */
705           play_sound(sounds[SND_STOMP], SOUND_CENTER_SPEAKER);
706           mode = FLAT;
707           base.xm = 0;
708
709           timer_start(&timer, 4000);
710       } else if (mode == FLAT) {
711           /* Kick! */
712           play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER);
713
714           if (player->base.x < base.x + (base.width/2)) {
715               base.xm = 5;
716               dir = RIGHT;
717           } else {
718               base.xm = -5;
719               dir = LEFT;
720           }
721
722           mode = KICK;
723       }
724
725       make_player_jump(player);
726               
727       add_score(base.x - scroll_x, base.y, 25 * score_multiplier);
728       score_multiplier++;
729       return;
730   }
731 }
732
733 void
734 BadGuy::collision(void *p_c_object, int c_object, CollisionType type)
735 {
736   BadGuy* pbad_c    = NULL;
737
738   if(type == COLLISION_BUMP) {
739     bump();
740     return;
741   }
742   if(type == COLLISION_SQUICH) {
743     Player* player = static_cast<Player*>(p_c_object);
744     squich(player);
745     return;
746   }
747
748   switch (c_object)
749     {
750     case CO_BULLET:
751       if(kind == BAD_BOMB || kind == BAD_STALACTITE || kind == BAD_FLAME)
752         return;
753
754       dying = DYING_FALLING;
755       base.ym = -8;
756
757       /* Gain some points: */
758       if (kind == BAD_BSOD)
759         add_score(base.x - scroll_x, base.y,
760                   50 * score_multiplier);
761       else if (kind == BAD_LAPTOP)
762         add_score(base.x - scroll_x, base.y,
763                   25 * score_multiplier);
764       else if (kind == BAD_MONEY)
765         add_score(base.x - scroll_x, base.y,
766                   50 * score_multiplier);
767
768       /* Play death sound: */
769       play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
770       break;
771
772     case CO_BADGUY:
773       pbad_c = (BadGuy*) p_c_object;
774       if(kind == BAD_LAPTOP && mode == KICK)
775         {
776           /* We're in kick mode, kill the other guy
777              and yourself(wuahaha) : */
778
779           pbad_c->dying = DYING_FALLING;
780           pbad_c->base.ym = -8;
781           play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
782
783           add_score(base.x - scroll_x,
784                     base.y, 100);
785                   
786           dying = DYING_FALLING;
787           base.ym = -8;
788
789           add_score(pbad_c->base.x - scroll_x,
790                     pbad_c->base.y, 100);
791         }
792       break;
793     }
794 }
795
796 //---------------------------------------------------------------------------
797
798 void load_badguy_gfx()
799 {
800   /* (BSOD) */
801   texture_load(&img_bsod_left[0], datadir +
802                "/images/shared/bsod-left-0.png",
803                USE_ALPHA);
804
805   texture_load(&img_bsod_left[1], datadir +
806                "/images/shared/bsod-left-1.png",
807                USE_ALPHA);
808
809   texture_load(&img_bsod_left[2], datadir +
810                "/images/shared/bsod-left-2.png",
811                USE_ALPHA);
812
813   texture_load(&img_bsod_left[3], datadir +
814                "/images/shared/bsod-left-3.png",
815                USE_ALPHA);
816
817   texture_load(&img_bsod_right[0], datadir +
818                "/images/shared/bsod-right-0.png",
819                USE_ALPHA);
820
821   texture_load(&img_bsod_right[1], datadir +
822                "/images/shared/bsod-right-1.png",
823                USE_ALPHA);
824
825   texture_load(&img_bsod_right[2], datadir +
826                "/images/shared/bsod-right-2.png",
827                USE_ALPHA);
828
829   texture_load(&img_bsod_right[3], datadir +
830                "/images/shared/bsod-right-3.png",
831                USE_ALPHA);
832
833   texture_load(&img_bsod_squished_left, datadir +
834                "/images/shared/bsod-squished-left.png",
835                USE_ALPHA);
836
837   texture_load(&img_bsod_squished_right, datadir +
838                "/images/shared/bsod-squished-right.png",
839                USE_ALPHA);
840
841   texture_load(&img_bsod_falling_left, datadir +
842                "/images/shared/bsod-falling-left.png",
843                USE_ALPHA);
844
845   texture_load(&img_bsod_falling_right, datadir +
846                "/images/shared/bsod-falling-right.png",
847                USE_ALPHA);
848
849
850   /* (Laptop) */
851
852   texture_load(&img_laptop_left[0], datadir +
853                "/images/shared/laptop-left-0.png",
854                USE_ALPHA);
855
856   texture_load(&img_laptop_left[1], datadir +
857                "/images/shared/laptop-left-1.png",
858                USE_ALPHA);
859
860   texture_load(&img_laptop_left[2], datadir +
861                "/images/shared/laptop-left-2.png",
862                USE_ALPHA);
863
864   texture_load(&img_laptop_right[0], datadir +
865                "/images/shared/laptop-right-0.png",
866                USE_ALPHA);
867
868   texture_load(&img_laptop_right[1], datadir +
869                "/images/shared/laptop-right-1.png",
870                USE_ALPHA);
871
872   texture_load(&img_laptop_right[2], datadir +
873                "/images/shared/laptop-right-2.png",
874                USE_ALPHA);
875
876   texture_load(&img_laptop_flat_left, datadir +
877                "/images/shared/laptop-flat-left.png",
878                USE_ALPHA);
879
880   texture_load(&img_laptop_flat_right, datadir +
881                "/images/shared/laptop-flat-right.png",
882                USE_ALPHA);
883
884   texture_load(&img_laptop_falling_left, datadir +
885                "/images/shared/laptop-falling-left.png",
886                USE_ALPHA);
887
888   texture_load(&img_laptop_falling_right, datadir +
889                "/images/shared/laptop-falling-right.png",
890                USE_ALPHA);
891
892
893   /* (Money) */
894
895   texture_load(&img_money_left[0], datadir +
896                "/images/shared/bag-left-0.png",
897                USE_ALPHA);
898
899   texture_load(&img_money_left[1], datadir +
900                "/images/shared/bag-left-1.png",
901                USE_ALPHA);
902
903   texture_load(&img_money_right[0], datadir +
904                "/images/shared/bag-right-0.png",
905                USE_ALPHA);
906
907   texture_load(&img_money_right[1], datadir +
908                "/images/shared/bag-right-1.png",
909                USE_ALPHA);
910
911   /* Mr. Bomb */
912   for(int i=0; i<4; ++i) {
913       char num[4];
914       snprintf(num, 4, "%d", i);
915       texture_load(&img_mrbomb_left[i],
916               datadir + "/images/shared/mrbomb-left-" + num + ".png", USE_ALPHA);
917       texture_load(&img_mrbomb_right[i],
918               datadir + "/images/shared/mrbomb-right-" + num + ".png", USE_ALPHA);
919   }
920   texture_load(&img_mrbomb_ticking_left,
921           datadir + "/images/shared/mrbombx-left-0.png", USE_ALPHA);
922   texture_load(&img_mrbomb_ticking_right,
923           datadir + "/images/shared/mrbombx-right-0.png", USE_ALPHA);
924   texture_load(&img_mrbomb_explosion,
925           datadir + "/images/shared/mrbomb-explosion.png", USE_ALPHA);
926
927   /* stalactite */
928   texture_load(&img_stalactite, 
929           datadir + "/images/shared/stalactite.png", USE_ALPHA);
930   texture_load(&img_stalactite_broken,
931           datadir + "/images/shared/stalactite-broken.png", USE_ALPHA);
932
933   /* flame */
934   texture_load(&img_flame[0],
935           datadir + "/images/shared/flame-0.png", USE_ALPHA);
936   texture_load(&img_flame[1],
937           datadir + "/images/shared/flame-1.png", USE_ALPHA);  
938 }
939
940 void free_badguy_gfx()
941 {
942   for (int i = 0; i < 4; i++)
943     {
944       texture_free(&img_bsod_left[i]);
945       texture_free(&img_bsod_right[i]);
946     }
947
948   texture_free(&img_bsod_squished_left);
949   texture_free(&img_bsod_squished_right);
950
951   texture_free(&img_bsod_falling_left);
952   texture_free(&img_bsod_falling_right);
953
954   for (int i = 0; i < 3; i++)
955     {
956       texture_free(&img_laptop_left[i]);
957       texture_free(&img_laptop_right[i]);
958     }
959
960   texture_free(&img_laptop_flat_left);
961   texture_free(&img_laptop_flat_right);
962
963   texture_free(&img_laptop_falling_left);
964   texture_free(&img_laptop_falling_right);
965
966   for (int i = 0; i < 2; i++)
967     {
968       texture_free(&img_money_left[i]);
969       texture_free(&img_money_right[i]);
970     }
971
972   for(int i = 0; i < 4; i++) {
973       texture_free(&img_mrbomb_left[i]);
974       texture_free(&img_mrbomb_right[i]);
975   }
976
977   texture_free(&img_mrbomb_ticking_left);
978   texture_free(&img_mrbomb_ticking_right);
979   texture_free(&img_mrbomb_explosion);
980
981   texture_free(&img_stalactite);
982   texture_free(&img_stalactite_broken);
983
984   texture_free(&img_flame[0]);
985   texture_free(&img_flame[1]);
986 }
987
988 // EOF //