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