Initial push
[shermanaquarium] / sherman-aquarium / shermans / fish.c
diff --git a/sherman-aquarium/shermans/fish.c b/sherman-aquarium/shermans/fish.c
new file mode 100644 (file)
index 0000000..3122c01
--- /dev/null
@@ -0,0 +1,1025 @@
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "aquarium.h"
+#include "draw.h"
+#include "fish.h"
+#include "bottom.h"
+#include "soundeffects.h"
+
+
+
+/* Data for fishes */
+
+static float fish1_speed[4] = { 1.0, 1.0, 1.0, 1.0 };
+static float fish2_speed[4] = { 0.6, 0.6, 0.6, 0.6 };
+static float fish3_speed[4] = { 1.1, 1.1, 1.1, 1.1 };
+static float fish4_speed[4] = { 1.0, 1.0, 1.0, 1.0 };
+static float fish5_speed[7] = { 0.8, 0.8, 0.7, 0.5, 0.7, 0.8, 0.8 };
+static float fish6_speed[4] = { 1.2, 1.2, 1.2, 1.2 };
+
+static float squid_speed[7] = { 0.1, 3.0, 3.0, 3.0, 3.0, 1.5, 1.0 };
+static float swordfish_speed[4] = { 1.4, 1.4, 1.4, 1.4 };
+static float blowfish_speed[4] = { 0.6, 0.6, 0.6, 0.6 };
+static float ernest_speed[4] = { 0.8, 0.8, 0.8, 0.8 };
+static float hunter_speed[4] = { 1.1, 1.1, 1.1, 1.1 };
+static float lori_speed[4] = { 0.8, 0.8, 0.8, 0.8 };
+static float prey_speed[4] = { 1.3, 1.3, 1.3, 1.3 };
+static float sherman_speed[14] =
+    { 1.5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.5, 1.75, 2.25, 2.5, 2.5, 2.5 };
+static float fillmore_speed[15] =
+    { 0.7, 0.7, 0.7, 0.7, 0.8, 0.9, 1.0, 1.0, 1.0, 0.7, 0.5, 0.5, 0.5, 0.6, 0.7 };
+
+static float prey_hunter_speed[7] = {1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5};
+static float blowup_speed[2] = {0.1, 0.1};
+
+static float bdweller_speed[4] = {0.01, 0.01, 0.01, 0.01};
+
+
+static int normal_animation[4] =    { 0, 1, 2, 1 };
+static int sherman_animation[14] =  { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 0 };
+static int fillmore_animation[15] = { 0, 1, 2, 3, 4, 5, 6, 6, 6, 7, 8, 9, 10, 11,  0 };
+
+static int squid_animation[7]={ 0, 1, 1, 1, 1, 1, 2};
+static int fish5_animation[7]={ 0, 0, 1, 2, 1, 0, 0};
+static int prey_hunter_animation[7]={0, 1, 2, 3, 4, 5, 6};
+
+
+static Fish_animation fish_animation[NUMOFFISHTYPES] = {
+    {"sherman/fish1.png",     3, 4, normal_animation,   fish1_speed     },
+    {"sherman/fish2.png",     3, 4, normal_animation,   fish2_speed     },
+    {"sherman/fish3.png",     3, 4, normal_animation,   fish3_speed     },
+    {"sherman/fish4.png",     3, 4, normal_animation,   fish4_speed     },
+    {"sherman/fish5.png",     3, 7, fish5_animation,    fish5_speed     },
+    {"sherman/fish6.png",     3, 4, normal_animation,   fish6_speed     },
+    {"sherman/squid.png",     3, 7, squid_animation,    squid_speed     },
+    {"sherman/swordfish.png", 3, 4, normal_animation,   swordfish_speed },
+    {"sherman/blowfish.png",  3, 4, normal_animation,   blowfish_speed  },
+    {"sherman/ernest.png",    3, 4, normal_animation,   ernest_speed    },
+    {"sherman/hunter.png",    3, 4, normal_animation,   hunter_speed    },
+    {"sherman/lori.png",      3, 4, normal_animation,   lori_speed      },
+    {"sherman/prey.png",      3, 4, normal_animation,   prey_speed      },
+    {"sherman/sherman.png",  11,14, sherman_animation,  sherman_speed   },
+    {"sherman/fillmore.png", 12,15, fillmore_animation, fillmore_speed  },
+    {"sherman/bdweller.png",  3, 4, normal_animation,   bdweller_speed  },
+    {"sherman/hawthorne.png", 3, 4, normal_animation,   bdweller_speed  },
+    {"sherman/megan.png",    11,14, sherman_animation,  sherman_speed   },
+
+};
+
+
+static Fish *fishes;
+static SA_Image blowup_data;
+static SA_Image prey_hunter_data;
+
+static SA_Image *fish_buffer;
+static Fish_settings fish_settings;
+
+static AquariumData *ad;
+static int scale_diff, num_fish, hunter_is, blowfish_is;
+
+Fish_settings *fish_get_settings_ptr(void)
+{
+    return &fish_settings;
+}
+
+Fish *fish_get_fishes_ptr(void)
+{
+    return fishes;
+}
+
+void fish_enter(void)
+{
+    int i;
+
+    for (i = 0; i < fish_settings.num_fish; i++){
+
+    /* completely off the screen, don't bother showing their escape */
+       if ( ((int)fishes[i].tx > (ad->xmax)) || 
+            ((int)fishes[i].tx < -(fishes[i].width)))
+           fishes[i].speed_mul = 0.0;
+       else    
+           fishes[i].speed_mul = 2.5;
+    }
+
+}
+
+void fish_leave(void)
+{
+    int i;
+
+    for (i = 0; i < fish_settings.num_fish; i++)
+       fishes[i].speed_mul = 1.0;
+
+}
+
+
+static int sel_fish(int j, int reset)
+{
+    static int local_fish[NUMOFFISHTYPES];
+
+    if(reset){
+       memset(&local_fish, 0, sizeof(int)*NUMOFFISHTYPES);
+       return 0;
+    }
+
+
+    /* The Bottom fish first */
+    if(fish_settings.bdweller > local_fish[BDWELLER]){
+       local_fish[BDWELLER]++;
+       return BDWELLER;
+    }
+
+    if(fish_settings.hawthorne > local_fish[HAWTHORNE]){
+       local_fish[HAWTHORNE]++;
+       return HAWTHORNE;
+    }
+
+
+    /* FIXME: Should randomize the order */
+
+    if(fish_settings.fish1 > local_fish[FISH1]){
+       local_fish[FISH1]++;
+       return FISH1;
+    }
+
+    if(fish_settings.fish2 > local_fish[FISH2]){
+       local_fish[FISH2]++;
+       return FISH2;
+    }
+
+    if(fish_settings.fish3 > local_fish[FISH3]){
+       local_fish[FISH3]++;
+       return FISH3;
+    }
+
+    if(fish_settings.fish4 > local_fish[FISH4]){
+       local_fish[FISH4]++;
+       return FISH4;
+    }
+
+    if(fish_settings.fish5 > local_fish[FISH5]){
+       local_fish[FISH5]++;
+       return FISH5;
+    }
+
+    if(fish_settings.fish6 > local_fish[FISH6]){
+       local_fish[FISH6]++;
+       return FISH6;
+    }
+
+
+    if(fish_settings.squid > local_fish[SQUID]){
+       local_fish[SQUID]++;
+       return SQUID;
+    }
+
+    if(fish_settings.swordfish > local_fish[SWORDFISH]){
+       local_fish[SWORDFISH]++;
+       return SWORDFISH;
+    }
+
+    if(fish_settings.blowfish > local_fish[BLOWFISH]){
+       local_fish[BLOWFISH]++;
+       return BLOWFISH;
+    }
+
+    if(fish_settings.ernest > local_fish[ERNEST]){
+       local_fish[ERNEST]++;
+       return ERNEST;
+    }
+
+    if(fish_settings.hunter > local_fish[HUNTER]){
+       local_fish[HUNTER]++;
+       return HUNTER;
+    }
+
+    if(fish_settings.lori > local_fish[LORI]){
+       local_fish[LORI]++;
+       return LORI;
+    }
+
+    if(fish_settings.prey > local_fish[PREY]){
+       local_fish[PREY]++;
+       return PREY;
+    }
+
+    if(fish_settings.sherman > local_fish[SHERMAN]){
+       local_fish[SHERMAN]++;
+       return SHERMAN;
+    }
+
+    if(fish_settings.fillmore > local_fish[FILLMORE]){
+       local_fish[FILLMORE]++;
+       return FILLMORE;
+    }
+
+    if(fish_settings.megan > local_fish[MEGAN]){
+       local_fish[MEGAN]++;
+       return MEGAN;
+    }
+    return 0;
+}
+
+
+static int get_fish(int start, int wantedfish)
+{
+    int i;
+    AquariumData *ad;
+    ad = aquarium_get_settings_ptr();
+
+    for(i = start + 1; i < fish_settings.num_fish; i++)
+       if(fishes[i].type == wantedfish) return i;
+  
+    return -1;
+}
+
+/* This rouitine handles both the eating fish happening and
+   the swordish hits a blowfish happening. */
+
+/* 
+   This rountine is the most messy you've seen. Sorry! 
+   But it works ok. :-)
+*/
+
+static void prey_hunter_hit()
+{
+    int i, j;
+    int victim_val=-1, doer_val=-1;
+
+    ad = aquarium_get_settings_ptr();
+
+
+    /* FIX ME: Scaling of hunter that eats prey */
+    //    if(fish_settings.scale_diff) return;
+
+    for(i = 0; i < fish_settings.num_fish; i++){
+       doer_val = get_fish(doer_val, HUNTER);
+       if(doer_val == -1) 
+           break;
+
+       /* Check if this one is eating right now. */
+       if(fishes[doer_val].num_animation == 7) 
+           continue;
+
+       victim_val = -1;
+
+       for(j = 0; j < fish_settings.num_fish; j++){
+           victim_val = get_fish(victim_val, PREY);
+           if(victim_val ==- 1) 
+               break;
+           if(fishes[victim_val].rev == fishes[doer_val].rev) 
+               continue;
+           
+
+           /* Don't eat already dead fish */
+           if(fishes[victim_val].is_dead) 
+               continue;
+
+           /* If parts of the prey is beyond the right edge, let it live */
+           if((fishes[victim_val].tx + fishes[victim_val].width) > (ad->xmax + ad->viewpoint_start_x)) 
+               continue;
+           /* If the fish is below the edge, let it live */
+           if((fishes[victim_val].y) > (ad->ymax + ad->viewpoint_start_y)) 
+               continue;
+
+           if(fishes[victim_val].tx < (ad->xmin - fishes[victim_val].width)) 
+               continue;
+
+           /* If the prey is too high, let it live */
+           if((fishes[victim_val].y) < ad->viewpoint_start_y) 
+               continue;
+
+
+
+      
+           if(abs((fishes[victim_val].y + fishes[victim_val].height) -
+                  (fishes[doer_val].y + fishes[doer_val].height)) > (fishes[doer_val].height / 2)) 
+               continue;
+
+
+      
+           /* rev=1 prey moves to towards right.*/
+           if(fishes[victim_val].rev){
+
+               if((fishes[doer_val].tx - fishes[victim_val].tx - fishes[victim_val].width)
+                  > (10 + fishes[victim_val].width) &&
+                  (fishes[doer_val].tx - fishes[victim_val].tx - fishes[victim_val].width)
+                  <(30 + fishes[victim_val].width)){
+                   if((fishes[victim_val].y + fishes[victim_val].height)
+                      >(fishes[doer_val].y + fishes[doer_val].height)) 
+                       fishes[doer_val].y += 2;
+                   if((fishes[victim_val].y + fishes[victim_val].height)
+                      <(fishes[doer_val].y + fishes[doer_val].height)) 
+                       fishes[doer_val].y -= 2;
+                   continue;
+               }
+
+               if((fishes[doer_val].tx - fishes[victim_val].tx - fishes[victim_val].width)
+                  > (10 + fishes[victim_val].width))
+                   continue;
+               if((fishes[doer_val].tx - fishes[victim_val].tx - fishes[victim_val].width)
+                  < fishes[victim_val].width) 
+                   continue;
+
+           }
+           else{
+               if((fishes[victim_val].tx - fishes[doer_val].width - fishes[doer_val].tx)
+                  > (10 + fishes[victim_val].width) &&
+                  (fishes[victim_val].tx - fishes[doer_val].width - fishes[doer_val].tx)
+                  < (30 + fishes[victim_val].width)){
+
+                   if((fishes[victim_val].y + fishes[victim_val].height)
+                      > (fishes[doer_val].y + fishes[doer_val].height)) 
+                       fishes[doer_val].y += 2;
+                   if((fishes[victim_val].y + fishes[victim_val].height)
+                      < (fishes[doer_val].y + fishes[doer_val].height)) 
+                       fishes[doer_val].y -= 2;
+                   continue;
+               }
+
+
+               if((fishes[victim_val].tx - fishes[doer_val].width - fishes[doer_val].tx)
+                  > (10 + fishes[victim_val].width)) 
+                   continue;
+               if((fishes[victim_val].tx - fishes[doer_val].width - fishes[doer_val].tx)
+                  < fishes[victim_val].width) 
+                   continue;
+           }
+                   
+
+           /* Sometimes the hunter decides not to eat the prey for various reasons. */
+           if(g_rand_int_range(ad->rnd, 0 , 100) > fish_settings.hunter_agr) 
+               continue;
+
+           //printf("hunter %d eats prey %d!\n",doer_val, victim_val);
+
+       
+
+
+           /* Play scream */
+           sound_eatscream();
+
+           /* Removing eaten prey */
+           aquarium_clean_image((int)fishes[victim_val].tx, fishes[victim_val].y - ad->viewpoint_start_y,
+                                fishes[victim_val].width, fishes[victim_val].height);
+
+
+           /*      if(doer_val>victim_val) doer_val--;
+
+           fish_settings.num_fish--;
+      
+           for(k=victim_val;k<fish_settings.num_fish;k++){
+               fishes[k]=fishes[k+1];
+           }
+           */
+
+           fishes[victim_val].is_dead = TRUE;
+
+           /* Towards left */
+      
+           if(!fishes[doer_val].rev)
+               fishes[doer_val].tx -= (prey_hunter_data.width - fishes[doer_val].width);
+
+           fishes[doer_val].image = &prey_hunter_data;
+           fishes[doer_val].frame = 0;
+           fishes[doer_val].width = prey_hunter_data.width;
+           fishes[doer_val].height =prey_hunter_data.height;
+           fishes[doer_val].animation = prey_hunter_animation;
+           fishes[doer_val].num_animation = 7;
+           fishes[doer_val].speed = prey_hunter_speed;
+           fishes[doer_val].fast_frame_change = 5.0;
+           break;
+      
+       }
+
+    }
+}
+
+/* Not quite ok yet...*/
+static void blowup_hit()
+{
+
+    int i,j;
+    int victim_val = -1, doer_val = -1;
+    AquariumData *ad;
+
+    ad = aquarium_get_settings_ptr();
+
+
+    for(i = 0;i < fish_settings.num_fish; i++){
+       doer_val = get_fish(doer_val, SWORDFISH);
+       if(doer_val == -1) 
+           break;
+
+       victim_val = -1;
+
+       for(j = 0;j < fish_settings.num_fish; j++){
+           victim_val = get_fish(victim_val, BLOWFISH);
+           if(victim_val == -1) 
+               break;
+
+           /* Is this blowfish blowing up? - Then take next.*/
+           if(fishes[victim_val].num_animation == 2) 
+               continue;
+
+           /* Don't bother zombie blowfish */
+           if(fishes[victim_val].is_dead) 
+               continue;
+       
+           if(fishes[victim_val].rev == fishes[doer_val].rev) 
+               continue;
+
+
+           /* If parts of the prey is beyond the right edge, let it live */
+           if((fishes[victim_val].tx + fishes[victim_val].width) 
+              > (ad->xmax + ad->viewpoint_start_x)) 
+               continue;
+           /* If the fish is below the edge, let it live */
+           if((fishes[victim_val].y) > (ad->ymax + ad->viewpoint_start_y)) 
+               continue;
+
+           if(fishes[victim_val].tx < (ad->xmin-fishes[victim_val].width)) 
+               continue;
+
+           /* If the prey is too high, let it live */
+           if((fishes[victim_val].y) < ad->viewpoint_start_y)
+               continue;
+
+      
+           if(abs(fishes[victim_val].y - fishes[doer_val].y)
+              > (fishes[victim_val].height / 2)) 
+               continue;
+
+
+      
+           /* rev=1 prey moves to towards right.*/
+           if(fishes[victim_val].rev){
+
+               if((fishes[doer_val].tx - fishes[victim_val].tx - fishes[victim_val].width)
+                  > 0 &&
+                  (fishes[doer_val].tx - fishes[victim_val].tx - fishes[victim_val].width)
+                  < 20){
+                   if((fishes[victim_val].y + fishes[victim_val].height / 2)
+                      > (fishes[doer_val].y + fishes[doer_val].height / 2)) 
+                       fishes[doer_val].y += 2;
+                   if((fishes[victim_val].y + fishes[victim_val].height / 2)
+                      <(fishes[doer_val].y + fishes[doer_val].height / 2))
+                       fishes[doer_val].y -= 2;
+                   continue;
+               }
+
+               if((fishes[doer_val].tx - fishes[victim_val].tx - fishes[victim_val].width)
+                  > 0) continue;
+               if((fishes[doer_val].tx - fishes[victim_val].tx - fishes[victim_val].width)
+                  < -10) continue;
+               /*
+                 printf("killing from right!\n vx:%d - vy:%d - dx:%d - dy:%d", 
+                 (int)fishes[victim_val].tx, fishes[victim_val].y,
+                 (int)fishes[doer_val].tx, fishes[doer_val].y);
+               */
+           }
+           else{
+               if((fishes[victim_val].tx - fishes[doer_val].width - fishes[doer_val].tx)
+                  > 0 &&
+                  (fishes[victim_val].tx - fishes[doer_val].width - fishes[doer_val].tx)
+                  < 20){
+
+                   if((fishes[victim_val].y + fishes[victim_val].height / 2) 
+                      >(fishes[doer_val].y + fishes[doer_val].height / 2)) 
+                       fishes[doer_val].y += 2;
+
+                   if((fishes[victim_val].y + fishes[victim_val].height / 2)
+                      <(fishes[doer_val].y + fishes[doer_val].height / 2)) 
+                       fishes[doer_val].y -= 2;
+
+                   continue;
+               }
+
+
+               if((fishes[victim_val].tx - fishes[doer_val].width - fishes[doer_val].tx)
+                  > 0) continue;
+               if((fishes[victim_val].tx - fishes[doer_val].width - fishes[doer_val].tx)
+                  < -10) continue;
+               /*
+                 printf("killing from left!\n vx:%d - vy:%d - dx:%d - dy:%d", 
+                 (int)fishes[victim_val].tx, fishes[victim_val].y,
+                 (int)fishes[doer_val].tx, fishes[doer_val].y);
+
+               */
+           }
+           /*
+             printf("swordfish hit %d blowfish %d!\n",doer_val, victim_val);
+           */
+
+           /* Sometimes the blowfish owns the swordfish money, and that can save its life ;-) */
+           if(g_rand_int_range(ad->rnd, 0, 100) > fish_settings.swordfish_agr) 
+               continue;
+
+           /* Removing the remains of the poor blowfish */
+           aquarium_clean_image((int)fishes[victim_val].tx, fishes[victim_val].y - ad->viewpoint_start_y,
+                                fishes[victim_val].width, fishes[victim_val].height);
+
+
+
+           /* Exploding blowfish */
+           sound_explode();
+
+           fishes[victim_val].image = &blowup_data;
+           fishes[victim_val].frame = 0;
+           fishes[victim_val].width = blowup_data.width;
+           fishes[victim_val].height = blowup_data.height;
+           fishes[victim_val].animation = normal_animation;
+           fishes[victim_val].num_animation = 2;
+           fishes[victim_val].speed = blowup_speed;
+           fishes[victim_val].fast_frame_change = 1.0;
+           break;
+      
+       }
+
+    }
+
+}
+
+
+
+void fish_update(void)
+{
+    int i,j;
+    AquariumData *ad;
+    Bottom_settings *bottom;
+
+    ad = aquarium_get_settings_ptr();
+    bottom = bottom_get_settings_ptr();
+
+    if((ad->special_action & 1) && fish_settings.eat)
+       prey_hunter_hit();
+
+    if((ad->special_action & 2) == 2 && fish_settings.explode)
+       blowup_hit();
+
+#ifdef DEBUG
+    printf("\t\t - Done special hits.\n");
+#endif
+
+
+    for(i = 0;i < fish_settings.num_fish; i++){
+       aquarium_clean_image((int) fishes[i].tx,
+                            fishes[i].y - ad->viewpoint_start_y,
+                            fishes[i].width, fishes[i].height);
+    }
+
+
+    for(i = 0; i < fish_settings.num_fish; i++){
+       if (fishes[i].frame >= (fishes[i].num_animation - 1)){
+           if(fish_settings.eat){
+               if(fishes[i].image == &prey_hunter_data){
+                   
+                   //printf("Done eating.Continue.\n");
+                   
+           
+                   /* Left movement is ok. */
+                   /*            else fishes[i].tx-=fishes[i].width-fish_buffer[HUNTER].width;*/
+           
+                   if(!fish_settings.scale_diff){
+                       if(fishes[i].rev) 
+                           fishes[i].tx += fishes[i].width - fish_buffer[HUNTER].width;
+                       fishes[i].width = fish_buffer[HUNTER].width;
+                       fishes[i].height = fish_buffer[HUNTER].height;
+                       fishes[i].image = &fish_buffer[HUNTER];
+                   } else {
+                       if(fishes[i].rev) 
+                           fishes[i].tx += fishes[i].width - fish_buffer[hunter_is].width;
+                       fishes[i].width = fish_buffer[hunter_is].width;
+                       fishes[i].height = fish_buffer[hunter_is].height;
+                       fishes[i].image = &fish_buffer[hunter_is];
+                   }
+
+                   fishes[i].animation = normal_animation;
+                   fishes[i].num_animation = 4;
+                   fishes[i].speed = hunter_speed;
+                   fishes[i].fast_frame_change = 1.0;
+                   fishes[i].frame = 0;
+           
+           
+               }
+           }
+       
+           if(fish_settings.explode) {
+         
+               if(fishes[i].image == &blowup_data){
+                   //printf("Done blowing up.\n");
+                   fishes[i].is_dead = TRUE;
+
+                   if(!fish_settings.scale_diff){
+                       fishes[i].width = fish_buffer[BLOWFISH].width;
+                       fishes[i].height = fish_buffer[BLOWFISH].height;
+                       fishes[i].image = &fish_buffer[BLOWFISH];
+                   } else {
+                       fishes[i].width = fish_buffer[blowfish_is].width;
+                       fishes[i].height = fish_buffer[blowfish_is].height;
+                       fishes[i].image = &fish_buffer[blowfish_is];
+                   }
+
+                   fishes[i].animation = normal_animation;
+                   fishes[i].num_animation = 4;
+                   fishes[i].speed = prey_speed;
+                   fishes[i].fast_frame_change = 1.0;
+                   fishes[i].frame = 0;
+
+
+                   /*
+                   fish_settings.num_fish--;
+                   for(k=i;k<fish_settings.num_fish;k++){
+                       fishes[k]=fishes[k+1];
+                       }*/
+
+           
+               }
+           }
+       }
+    }
+    
+    sel_fish(0, TRUE);
+
+    for (i = 0; i < fish_settings.num_fish; i++) {
+
+       if(fishes[i].is_dead == TRUE){
+
+           if(fish_settings.rebirth){
+               if(g_rand_int_range(ad->rnd, 0, 100) < 20){
+                   //              printf("Rebirth and salvation..\n");
+                   /* Salvation and rebirth...*/
+                   fishes[i].is_dead = FALSE;
+                   fishes[i].frame = g_rand_int_range(ad->rnd, 0, fishes[i].num_animation);
+
+
+                   if(g_rand_boolean(ad->rnd)){
+                       fishes[i].rev = 1;
+                       fishes[i].travel =
+                           g_rand_int_range(ad->rnd, 0, (ad->virtual_aquarium_x - ad->xmax) / 2) +
+                           fishes[i].width;
+                       fishes[i].tx = -fishes[i].width - fishes[i].travel;
+                   } else {
+                       fishes[i].rev = 0;
+                       fishes[i].travel = 
+                           g_rand_int_range(ad->rnd, 0, (ad->virtual_aquarium_x - ad->xmax) / 2) +
+                           fishes[i].width;
+                       fishes[i].tx = ad->xmax + fishes[i].travel;
+                   }
+                   fishes[i].y = g_rand_int_range(ad->rnd, 0, (ad->virtual_aquarium_y - fishes[i].height));
+
+                   fishes[i].speed_mul = 1.0 + g_rand_double_range(ad->rnd, -15.0 / 100.0, 15.0 / 100.0);
+               }
+
+           } else {
+               /* Don't draw zombie fish */
+               continue;
+           }
+       }
+       
+
+       /* frozen fish doesn't need to be handled, or drawn */
+       if (fishes[i].speed_mul == 0)
+           continue;
+
+       if((fishes[i].type == BDWELLER || fishes[i].type == HAWTHORNE) && !bottom->have_sea_floor)
+           continue;
+
+       /* move fish in horizontal direction, left or right */
+       /* Large aquarium, the fishes are shown more seldom */
+
+       if (!fishes[i].rev) {
+
+           fishes[i].tx -=
+               (fishes[i].speed[fishes[i].frame]) * (fishes[i].speed_mul * fish_settings.speed / 100);
+
+           if (fishes[i].tx < (-fishes[i].width - fishes[i].travel)) {
+               /* we moved out of bounds. change direction,
+                * position, speed. */
+
+               fishes[i].travel = g_rand_int_range(ad->rnd, 0, (ad->virtual_aquarium_x - ad->xmax) / 2) +
+                   fishes[i].width;
+               fishes[i].tx = -fishes[i].width - fishes[i].travel;
+               fishes[i].rev = 1;
+
+               /* If bottom creature, keep the the Y level */
+               if(fishes[i].type != BDWELLER && fishes[i].type != HAWTHORNE)
+                   fishes[i].y = g_rand_int_range(ad->rnd, 0, ad->virtual_aquarium_y - fishes[i].height);
+               
+
+               if (ad->proximity)
+                   fishes[i].speed_mul = 0;
+               else
+                   fishes[i].speed_mul = 1;
+
+           }
+       } else {
+
+
+           fishes[i].tx +=
+               (fishes[i].speed[fishes[i].frame]) * (fishes[i].speed_mul * fish_settings.speed / 100);
+
+
+           if (fishes[i].tx > ad->xmax + fishes[i].travel) {
+               /* we moved out of bounds. change direction,
+                * position, speed. */
+
+               fishes[i].travel = g_rand_int_range(ad->rnd, 0, (ad->virtual_aquarium_x - ad->xmax) / 2) +
+                   fishes[i].width;
+               fishes[i].tx = ad->xmax + fishes[i].travel;
+               fishes[i].rev = 0;
+
+               /* If bottom creature, keep the the Y level */
+               if(fishes[i].type != BDWELLER && fishes[i].type != HAWTHORNE)
+                   fishes[i].y = g_rand_int_range(ad->rnd, 0, ad->virtual_aquarium_y - fishes[i].height);
+
+               if (ad->proximity)
+                   fishes[i].speed_mul = 0;
+               else
+                   fishes[i].speed_mul = 1;
+
+           }
+       }
+
+       /* move fish in vertical position randomly by one pixel up or down */
+       /* If the fish last time moved up or down, larger chance that it does that again. */
+
+       j = g_rand_int_range(ad->rnd, 0, 16);
+
+       /* The bottondweller & hawthorne shall be still ;-) */
+       if(fishes[i].type == BDWELLER || fishes[i].type == HAWTHORNE) 
+           j = 0;
+
+       if (((fishes[i].updown == 1) && (j == 6 || j == 7 || j == 8))
+           || j == 8) {
+           fishes[i].y++;
+           fishes[i].updown = 1;
+       } else if (((fishes[i].updown == -1)
+                   && (j == 12 || j == 13 || j == 14)) || j == 12) {
+           fishes[i].y--;
+           fishes[i].updown = -1;
+       } else
+           fishes[i].updown = 0;
+#ifdef DEBUG
+       /*      printf("\t\t - Calling draw_fish()\n");*/
+#endif
+           /* animate fishes using fish_animation array */
+           aquarium_draw_image((int) fishes[i].tx,
+                               fishes[i].y - ad->viewpoint_start_y,
+                               fishes[i].animation[fishes[i].frame],
+                               fishes[i].rev, fishes[i].image);
+
+       /* switch to next swimming frame */
+
+
+       fishes[i].delay += fishes[i].speed[fishes[i].frame] * fishes[i].fast_frame_change;
+#ifdef DEGUG
+       printf("delay:%f speed:%f frame:%d num_ani:%d anipic:%d\n",
+              fishes[i].delay, fishes[i].speed[fishes[i].frame],fishes[i].frame, fishes[i].num_animation, fishes[i].animation[fishes[i].frame]);
+#endif
+       if (fishes[i].delay >= (7 * fishes[i].speed[fishes[i].frame])) {
+           if (fishes[i].frame >= (fishes[i].num_animation - 1)){
+               fishes[i].frame = 0;
+           }     
+           else fishes[i].frame ++;
+           fishes[i].delay = 0;
+       }
+
+    }
+}
+
+static void fish_flip(SA_Image *this_fish)
+{
+    int j, k, ypos;
+
+    if(this_fish->image != NULL){
+
+      this_fish->rev = g_malloc0(this_fish->width * 
+                                this_fish->full_height * 4 );
+    
+      for(j = 0;j < (this_fish->full_height); j++){
+       ypos = j * this_fish->width * 4;
+       for(k = 0; k < this_fish->width; k++){
+         this_fish->rev[ypos + (this_fish->width - k - 1) * 4]     = this_fish->image[ypos + k * 4];
+         this_fish->rev[ypos + (this_fish->width - k - 1) * 4 + 1] = this_fish->image[ypos + k * 4 + 1];
+         this_fish->rev[ypos + (this_fish->width - k - 1) * 4 + 2] = this_fish->image[ypos + k * 4 + 2];
+         this_fish->rev[ypos + (this_fish->width - k - 1) * 4 + 3] = this_fish->image[ypos + k * 4 + 3];
+       }
+      }
+    }
+}
+
+
+void fish_turn(void)
+{
+  int i, m;
+
+
+  if(fish_settings.scale_diff)
+      m = fish_settings.num_fish;
+  else 
+      m = NUMOFFISHTYPES;
+
+  for(i = 0; i < m; i++){
+      fish_flip(&fish_buffer[i]);
+  }
+
+  fish_flip(&blowup_data);
+  fish_flip(&prey_hunter_data);
+
+}
+
+
+void fish_init(void)
+{
+    int i, num_bottom_fish;
+    int type = 0, special_fish = 0;
+
+    Bottom_settings *bottom_settings;
+    
+    bottom_settings = bottom_get_settings_ptr();
+
+    /* Set up this for the rest of the life */
+    ad = aquarium_get_settings_ptr();
+
+    ad->special_action = 0;
+
+
+    /* Save settings for fish_exit() */
+    scale_diff = fish_settings.scale_diff;
+
+    /* 0 - 30 fishes */
+    if(fish_settings.type == RANDOM_POP_FISH)
+       fish_settings.num_fish = g_rand_int_range(ad->rnd, 1, 30);
+
+    num_fish = fish_settings.num_fish;
+
+    if(fish_settings.scale_diff)
+       fish_buffer = g_malloc0(sizeof(SA_Image) * fish_settings.num_fish);
+    else
+       fish_buffer = g_malloc0(sizeof(SA_Image) * NUMOFFISHTYPES);
+
+
+    fishes = g_malloc0(sizeof(Fish) * fish_settings.num_fish);
+
+    num_bottom_fish = bottom_settings->num_bottom_animals;
+
+    if(num_bottom_fish > num_fish)
+       num_bottom_fish = num_fish;
+
+    for (i = 0; i < fish_settings.num_fish; i++) {
+
+       if(fish_settings.type == RANDOM_FISH || fish_settings.type == RANDOM_POP_FISH) {
+
+           /* FIX ME! Bottom dweller and hawthorne chance !*/
+           if((i<num_bottom_fish) && (bottom_settings->have_sea_floor)) {
+
+               if(g_rand_boolean(ad->rnd)) 
+                   type = BDWELLER;
+               else type = HAWTHORNE;
+           }
+           else
+               do{
+                   type = g_rand_int_range(ad->rnd, 0, NUMOFFISHTYPES); 
+               } while(type == BDWELLER || type == HAWTHORNE);
+       }
+       else{
+           type = sel_fish(i, FALSE);
+       }
+
+
+       if(type == PREY) special_fish |= 1;
+       if(type == HUNTER) special_fish |= 2;
+       if(type == SWORDFISH) special_fish |= 4;
+       if(type == BLOWFISH) special_fish |= 8;
+
+
+       if(!fish_settings.scale_diff){
+
+           if (fish_buffer[type].image == NULL) {
+               load_image_n_scale(fish_animation[type].file,
+                                  &fish_buffer[type],
+                                  fish_animation[type].pics,
+                                  fish_settings.scale);
+
+           }
+
+           fishes[i].width = fish_buffer[type].width;
+           fishes[i].height = fish_buffer[type].height;
+
+           fishes[i].image = &fish_buffer[type];
+
+       } else {
+
+           if(type != HUNTER && type != BLOWFISH){
+               load_image_n_scale(fish_animation[type].file, &fish_buffer[i],
+                                  fish_animation[type].pics,
+                                  abs(fish_settings.scale + (g_rand_int_range(ad->rnd, -15, 15)) * fish_settings.scale / 100) );
+           } else {
+               if(type == HUNTER) hunter_is = i;
+               if(type == BLOWFISH) blowfish_is = i;
+
+               load_image_n_scale(fish_animation[type].file, &fish_buffer[i],
+                                  fish_animation[type].pics,
+                                  fish_settings.scale);
+           }
+
+           fishes[i].width = fish_buffer[i].width;
+           fishes[i].height = fish_buffer[i].height;
+
+           fishes[i].image = &fish_buffer[i];
+
+       }
+
+
+       fishes[i].num_animation = fish_animation[type].frames;
+       fishes[i].animation = fish_animation[type].animation;
+
+       fishes[i].speed = fish_animation[type].speed;
+
+
+       fishes[i].type = type;
+       fishes[i].frame = g_rand_int_range(ad->rnd, 0, fishes[i].num_animation);
+
+       fishes[i].rev = g_rand_boolean(ad->rnd);
+       fishes[i].tx = g_rand_int_range(ad->rnd, 0, ad->virtual_aquarium_x - fishes[i].width);
+
+       fishes[i].speed_mul =  1.0 + g_rand_double_range(ad->rnd, -15.0 / 100.0, 15.0 / 100.0);
+
+
+       fishes[i].fast_frame_change = 1.0;
+
+       fishes[i].is_dead = FALSE;
+
+       fishes[i].updown = 0;
+       fishes[i].travel = g_rand_int_range(ad->rnd, 0, (ad->virtual_aquarium_x - ad->xmax) / 2) + fishes[i].width;
+       fishes[i].y = g_rand_int_range(ad->rnd, 0, ad->virtual_aquarium_y - fishes[i].height);
+
+    }
+
+    
+    if((special_fish & 3) == 3 && fish_settings.eat){
+       load_image_n_scale("sherman/eating.png", 
+                          &prey_hunter_data,
+                          7, fish_settings.scale);
+
+       ad->special_action |= 1;
+    } else
+       prey_hunter_data.pixbuf = NULL;
+
+    if((special_fish & 12) == 12 && fish_settings.explode){
+       load_image_n_scale("sherman/blowup.png", 
+                          &blowup_data,
+                          7, fish_settings.scale);
+
+       ad->special_action|=2;
+    }
+    else
+       blowup_data.pixbuf = NULL;
+
+}
+
+
+void fish_exit(void)
+{
+    int i,j;
+
+    if(scale_diff)
+       j = num_fish;
+    else
+       j = NUMOFFISHTYPES;
+
+    for(i = 0; i < j; i++){
+       if(fish_buffer[i].pixbuf != NULL){
+           g_object_unref(fish_buffer[i].pixbuf);
+
+           if(fish_buffer[i].rev !=NULL)
+               g_free(fish_buffer[i].rev);
+       }
+    }
+
+    
+    if(blowup_data.pixbuf != NULL){
+       g_object_unref(blowup_data.pixbuf);
+
+       if(blowup_data.rev != NULL)
+           g_free(blowup_data.rev);
+
+    }
+
+    if(prey_hunter_data.pixbuf != NULL){
+       g_object_unref(prey_hunter_data.pixbuf);
+
+       if(prey_hunter_data.rev != NULL)
+           g_free(prey_hunter_data.rev);
+    }
+
+    g_free(fish_buffer);
+    g_free(fishes);
+}
+
+