]> icculus.org git repositories - taylor/freespace2.git/blob - src/menuui/fishtank.cpp
Initial revision
[taylor/freespace2.git] / src / menuui / fishtank.cpp
1 /*
2  * $Logfile: /Freespace2/code/MenuUI/fishtank.cpp $
3  * $Revision$
4  * $Date$
5  * $Author$
6  *
7  * bloop
8  *
9  * $Log$
10  * Revision 1.1  2002/05/03 03:28:09  root
11  * Initial revision
12  *
13  * 
14  * 3     9/01/99 10:09a Dave
15  * Pirate bob.
16  * 
17  * 2     8/26/99 9:45a Dave
18  * First pass at easter eggs and cheats.
19  * 
20  *
21  * $NoKeywords: $
22  */
23
24 #include "animplay.h"
25 #include "packunpack.h"
26 #include "2d.h"
27 #include "fishtank.h"
28 #include "freespace.h"
29 #include "gamesequence.h"
30
31 // fish
32 typedef struct fish {
33         float x, y;                                             // x and y coords
34         float   x_speed, y_speed;               // x and y speed
35         int     left;                                           // left or right
36         anim_instance *a;                               // tha animation
37         int     onscreen;                               
38         int     swimming;                               // whee
39 } fish;
40 #define MAX_FISH                                        12
41 fish Fish[MAX_FISH];
42
43 // fish anim name
44 #define FISH_LEFT_ANIM_NAME                     "f_left.ani"
45 #define FISH_RIGHT_ANIM_NAME                    "f_right.ani"
46
47 #define FISH_ANIM_WIDTH                 100
48 #define FISH_ANIM_HEIGHT                30
49
50 anim *Fish_left_anim = NULL;
51 anim *Fish_right_anim = NULL;
52
53 int Fish_inited = 0;
54
55 void fish_generate()
56 {
57         fish *f;
58         int idx;
59
60         if(!Fish_inited){
61                 return;
62         }
63
64         // bogus anims
65         if((Fish_left_anim == NULL) || (Fish_right_anim == NULL)){
66                 return;
67         }
68
69         // find a free fish
70         f = NULL;
71         for(idx=0; idx<MAX_FISH; idx++){
72                 if(!Fish[idx].swimming){
73                         f = &Fish[idx];
74                 }
75         }
76
77         // no fish left
78         if(f == NULL){
79                 return;
80         }       
81
82         // left or right
83         f->left = frand_range(0.0f, 1.0f) < 0.5f ? 0 : 1;
84
85         // start location
86         if(f->left){
87                 f->x = gr_screen.max_w + frand_range(0.0f, 50.0f);
88         } else {
89                 f->x = frand_range(0.0f, -50.0f) - FISH_ANIM_WIDTH;
90         }
91         f->y = frand_range(-40.0f, (float)gr_screen.max_h + 40.0f);
92
93         // speed
94         if(f->left){
95                 f->x_speed = frand_range(-1.0f, -15.0f);
96         } else {
97                 f->x_speed = frand_range(1.0f, 15.0f);
98         }
99         f->y_speed = frand_range(0.0f, 1.0f) < 0.5f ? frand_range(1.0f, 4.0f) : frand_range(-1.0f, -4.0f);
100
101         // all fish start out offscreen
102         f->onscreen = 0;
103
104         // he's swimming
105         f->swimming = 1;
106
107         // anim instance
108         anim_play_struct aps;
109
110         if(f->left){
111                 anim_play_init(&aps, Fish_left_anim, (int)f->x, (int)f->y);             
112                 f->a = anim_play(&aps);
113
114                 // doh. cancel him
115                 if(f->a == NULL){
116                         f->swimming = 0;
117                 } else {
118                         f->a->screen_id = GS_STATE_MAIN_MENU;
119                         f->a->looped = 1;
120                         f->a->framerate_independent = 1;
121                 }
122         } else {
123                 anim_play_init(&aps, Fish_right_anim, (int)f->x, (int)f->y);            
124                 f->a = anim_play(&aps);
125
126                 // doh. cancel him
127                 if(f->a == NULL){
128                         f->swimming = 0;
129                 } else {
130                         f->a->screen_id = GS_STATE_MAIN_MENU;
131                         f->a->looped = 1;
132                         f->a->framerate_independent = 1;
133                 }
134         }
135 }
136
137 void fish_flush(fish *f)
138 {
139         // bogus
140         if(f == NULL){
141                 return;
142         }
143
144         // release his render instance
145         if(f->a != NULL){
146                 anim_release_render_instance(f->a);
147                 f->a = NULL;
148         }
149
150         // no longer swimming
151         f->swimming = 0;
152 }
153
154 void fishtank_start()
155 {
156         int idx;
157
158         if(Fish_inited){
159                 return;
160         }
161
162         // try and load the fish anim
163         Fish_left_anim = anim_load(FISH_LEFT_ANIM_NAME);
164         if(Fish_left_anim == NULL){
165                 return;
166         }
167         Fish_right_anim = anim_load(FISH_RIGHT_ANIM_NAME);
168         if(Fish_right_anim == NULL){
169                 return;
170         }
171
172         // no anim instances
173         for(idx=0; idx<MAX_FISH; idx++){
174                 Fish[idx].a = NULL;
175                 Fish[idx].swimming = 0;
176         }       
177
178         Fish_inited = 1;
179
180         // generate a random # of fish
181         int count = (int)frand_range(1.0f, (float)(MAX_FISH - 1));
182         for(idx=0; idx<count; idx++){
183                 fish_generate();
184         }               
185 }
186
187 void fishtank_stop()
188 {
189         int idx;
190
191         if(!Fish_inited){
192                 return;
193         }
194
195         // release stuff                
196         for(idx=0; idx<MAX_FISH; idx++){
197                 if(Fish[idx].a != NULL){
198                         anim_release_render_instance(Fish[idx].a);
199                         Fish[idx].a = NULL;
200                 }
201                 Fish[idx].swimming = 0;
202         }
203         if(Fish_left_anim != NULL){
204                 anim_free(Fish_left_anim);
205                 Fish_left_anim = NULL;
206         }
207         if(Fish_right_anim != NULL){
208                 anim_free(Fish_right_anim);
209                 Fish_right_anim = NULL;
210         }       
211
212         Fish_inited = 0;
213 }
214
215 void fishtank_process()
216 {
217         int idx, onscreen;
218         fish *f;
219
220         if(!Fish_inited){
221                 return;
222         }
223
224         // process all fish
225         for(idx=0; idx<MAX_FISH; idx++){                
226                 f = &Fish[idx];
227
228                 // not swimming?
229                 if(!f->swimming){
230                         continue;
231                 }
232
233                 // move him along
234                 f->x += f->x_speed * flFrametime;
235                 f->y += f->y_speed * flFrametime;
236
237                 // is he currently onscreen ?
238                 onscreen = 0;
239                 if( (f->x < (float)gr_screen.max_w) && ((f->x + FISH_ANIM_WIDTH) >= 0.0f) &&
240                          (f->y < (float)gr_screen.max_h) && ((f->y + FISH_ANIM_HEIGHT) >= 0.0f) ){
241                         onscreen = 1;
242                 }
243
244                 // if he was onscreen before, but is no longer, flush him and make a new fish
245                 if(f->onscreen && !onscreen){
246                         fish_flush(f);
247
248                         fish_generate();
249                         continue;
250                 }
251
252                 // otherwise just mark his current status
253                 f->onscreen = onscreen;
254
255                 // render
256                 if(f->onscreen){
257                         // set coords
258                         f->a->x = (int)f->x;
259                         f->a->y = (int)f->y;
260
261                         anim_render_one(GS_STATE_MAIN_MENU, f->a, flFrametime);
262                 }
263         }
264 }
265