]> icculus.org git repositories - taylor/freespace2.git/blob - src/weapon/muzzleflash.cpp
deal with timestamp issue when calculating submodel rotation
[taylor/freespace2.git] / src / weapon / muzzleflash.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/Weapon/MuzzleFlash.cpp $
11  * $Revision$
12  * $Date$
13  * $Author$
14  *
15  * all sorts of cool stuff about ships
16  *
17  * $Log$
18  * Revision 1.4  2005/10/01 22:04:58  taylor
19  * fix FS1 (de)briefing voices, the directory names are different in FS1
20  * hard code the table values so that the fs1.vp file isn't needed
21  * hard code a mission fix for sm2-08a since a have no idea how to fix it otherwise
22  * generally cleanup some FS1 code
23  * fix volume sliders in the options screen that never went all the way up
24  *
25  * Revision 1.3  2002/06/09 04:41:29  relnev
26  * added copyright header
27  *
28  * Revision 1.2  2002/05/07 03:16:53  theoddone33
29  * The Great Newline Fix
30  *
31  * Revision 1.1.1.1  2002/05/03 03:28:11  root
32  * Initial import.
33  *
34  * 
35  * 7     7/08/99 10:53a Dave
36  * New multiplayer interpolation scheme. Not 100% done yet, but still
37  * better than the old way.
38  * 
39  * 6     5/18/99 1:30p Dave
40  * Added muzzle flash table stuff.
41  * 
42  * 5     4/25/99 3:02p Dave
43  * Build defines for the E3 build.
44  * 
45  * 4     4/12/99 11:03p Dave
46  * Removed contrails and muzzle flashes from MULTIPLAYER_BETA builds.
47  * 
48  * 3     3/19/99 9:52a Dave
49  * Checkin to repair massive source safe crash. Also added support for
50  * pof-style nebulae, and some new weapons code.
51  * 
52  * 2     1/08/99 2:08p Dave
53  * Fixed software rendering for pofview. Super early support for AWACS and
54  * beam weapons.
55  * 
56  * 
57  * $NoKeywords: $
58  */
59
60 #include "object.h"
61 #include "timer.h"
62 #include "systemvars.h"
63 #include "linklist.h"
64 #include "parselo.h"
65 #include "muzzleflash.h"
66 #include "bmpman.h"
67 #include "particle.h"
68
69 // ---------------------------------------------------------------------------------------------------------------------
70 // MUZZLE FLASH DEFINES/VARS
71 // 
72
73 // muzzle flash info - read from a table
74 #define MAX_MFLASH_NAME_LEN             32
75 #define MAX_MFLASH_BLOBS                        5
76 typedef struct mflash_info {
77         char            name[MAX_MFLASH_NAME_LEN+1];
78         char            blob_names[MAX_MFLASH_BLOBS][MAX_MFLASH_NAME_LEN+1];                    // blob anim name
79         int             blob_anims[MAX_MFLASH_BLOBS];                                                                                   // blob anim
80         float           blob_offset[MAX_MFLASH_BLOBS];                                                                          // blob offset from muzzle
81         float           blob_radius[MAX_MFLASH_BLOBS];                                                                          // blob radius
82         int             num_blobs;                                                                                                                                      // # of blobs
83 } mflash_info;
84 mflash_info Mflash_info[MAX_MUZZLE_FLASH_TYPES];
85 int Num_mflash_types = 0;
86
87 #define MAX_MFLASH                              50
88
89 // Stuff for missile trails doesn't need to be saved or restored... or does it?
90 /*
91 typedef struct mflash { 
92         struct  mflash * prev;
93         struct  mflash * next;
94
95         ubyte           type;                                                                                                                                                   // muzzle flash type
96         int             blobs[MAX_MFLASH_BLOBS];                                                                                                // blobs
97 } mflash;
98
99 int Num_mflash = 0;
100 mflash Mflash[MAX_MFLASH];
101
102 mflash Mflash_free_list;
103 mflash Mflash_used_list;
104 */
105
106 // ---------------------------------------------------------------------------------------------------------------------
107 // MUZZLE FLASH FUNCTIONS
108 // 
109
110 // initialize muzzle flash stuff for the whole game
111 void mflash_game_init()
112 {
113 #ifndef MAKE_FS1
114         mflash_info bogus;
115         mflash_info *m; 
116         char name[MAX_MFLASH_NAME_LEN];
117         float offset, radius;
118         int idx;
119
120         try {
121                 read_file_text("mflash.tbl");
122                 reset_parse();
123
124                 // header
125                 required_string("#Muzzle flash types");
126
127                 // read em in
128                 Num_mflash_types = 0;
129                 while(optional_string("$Mflash:")){
130                         if(Num_mflash_types < MAX_MUZZLE_FLASH_TYPES){
131                                 m = &Mflash_info[Num_mflash_types++];
132                         } else {
133                                 m = &bogus;
134                         }
135                         memset(m, 0, sizeof(mflash_info));
136                         for(idx=0; idx<MAX_MFLASH_BLOBS; idx++){
137                                 m->blob_anims[idx] = -1;
138                         }
139
140                         required_string("+name:");
141                         stuff_string(m->name, F_NAME, NULL);
142
143                         // read in all blobs
144                         m->num_blobs = 0;
145                         while(optional_string("+blob_name:")){
146                                 stuff_string(name, F_NAME, NULL, MAX_MFLASH_NAME_LEN);
147
148                                 required_string("+blob_offset:");
149                                 stuff_float(&offset);
150
151                                 required_string("+blob_radius:");
152                                 stuff_float(&radius);
153
154                                 // if we have room left
155                                 if(m->num_blobs < MAX_MFLASH_BLOBS){
156                                         SDL_strlcpy(m->blob_names[m->num_blobs], name, MAX_MFLASH_NAME_LEN);
157                                         m->blob_offset[m->num_blobs] = offset;
158                                         m->blob_radius[m->num_blobs] = radius;
159
160                                         m->num_blobs++;
161                                 }
162                         }
163                 }
164
165                 // close
166                 required_string("#end");
167         } catch (parse_error_t rval) {
168                 Error(LOCATION, "Error parsing 'mflash.tbl'\r\nError code = %i.\r\n", (int)rval);
169         }
170 #else
171         // hardcoded FS1 values
172         int idx;
173         mflash_info *m;
174
175         Num_mflash_types = 0;
176         m = &Mflash_info[Num_mflash_types++];
177
178         memset(m, 0, sizeof(mflash_info));
179
180         for (idx=0; idx<MAX_MFLASH_BLOBS; idx++) {
181                 m->blob_anims[idx] = -1;
182         }
183
184         SDL_strlcpy(m->name, "mflash_small", MAX_MFLASH_NAME_LEN);
185
186         m->num_blobs = 4;
187         SDL_assert(m->num_blobs <= MAX_MFLASH_BLOBS);
188
189         idx = 0;
190         SDL_strlcpy(m->blob_names[idx], "expmissilehit1", MAX_MFLASH_NAME_LEN);
191         m->blob_offset[idx] = 1.0f;
192         m->blob_radius[idx] = 6.0f;
193
194         idx++;
195         SDL_strlcpy(m->blob_names[idx], "expmissilehit1", MAX_MFLASH_NAME_LEN);
196         m->blob_offset[idx] = 4.5f;
197         m->blob_radius[idx] = 4.0f;
198
199         idx++;
200         SDL_strlcpy(m->blob_names[idx], "expmissilehit1", MAX_MFLASH_NAME_LEN);
201         m->blob_offset[idx] = 6.0f;
202         m->blob_radius[idx] = 3.0f;
203
204         idx++;
205         SDL_strlcpy(m->blob_names[idx], "expmissilehit1", MAX_MFLASH_NAME_LEN);
206         m->blob_offset[idx] = 8.5f;
207         m->blob_radius[idx] = 3.0f;
208 #endif
209 }
210
211 // initialize muzzle flash stuff for the level
212 void mflash_level_init()
213 {
214         int i, idx;
215         int num_frames, fps;
216
217         /*
218         Num_mflash = 0;
219         list_init( &Mflash_free_list );
220         list_init( &Mflash_used_list );
221
222         // Link all object slots into the free list
223         for (i=0; i<MAX_MFLASH; i++)    {
224                 memset(&Mflash[i], 0, sizeof(mflash));
225                 list_append(&Mflash_free_list, &Mflash[i] );
226         }
227         */
228
229         // load up all anims
230         for(i=0; i<Num_mflash_types; i++){
231                 // blobs
232                 for(idx=0; idx<Mflash_info[i].num_blobs; idx++){
233                         Mflash_info[i].blob_anims[idx] = -1;
234                         Mflash_info[i].blob_anims[idx] = bm_load_animation(Mflash_info[i].blob_names[idx], &num_frames, &fps, 1);
235                         SDL_assert(Mflash_info[i].blob_anims[idx] >= 0);
236                 }
237         }
238 }
239
240 // shutdown stuff for the level
241 void mflash_level_close()
242 {
243 }
244
245 // create a muzzle flash on the guy
246 void mflash_create(vector *gun_pos, vector *gun_dir, int mflash_type)
247 {       
248         // mflash *mflashp;
249         mflash_info *mi;
250         particle_info p;
251         int idx;
252
253         // standalone server should never create trails
254         if(Game_mode & GM_STANDALONE_SERVER){
255                 return;
256         }
257
258         // illegal value
259         if((mflash_type >= Num_mflash_types) || (mflash_type < 0)){
260                 return;
261         }
262
263         /*
264         if (Num_mflash >= MAX_MFLASH ) {
265                 #ifndef NDEBUG
266                 mprintf(("Muzzle flash creation failed - too many trails!\n" ));
267                 #endif
268                 return;
269         }
270
271         // Find next available trail
272         mflashp = GET_FIRST(&Mflash_free_list);
273         SDL_assert( mflashp != &Mflash_free_list );             // shouldn't have the dummy element
274
275         // remove trailp from the free list
276         list_remove( &Mflash_free_list, mflashp );
277         
278         // insert trailp onto the end of used list
279         list_append( &Mflash_used_list, mflashp );
280
281         // store some stuff
282         mflashp->type = (ubyte)mflash_type;     
283         */
284
285         // create the actual animations 
286         mi = &Mflash_info[mflash_type];
287         for(idx=0; idx<mi->num_blobs; idx++){           
288
289                 // bogus anim
290                 if(mi->blob_anims[idx] < 0){
291                         continue;
292                 }
293                 
294                 // fire it up
295                 memset(&p, 0, sizeof(particle_info));
296                 vm_vec_scale_add(&p.pos, gun_pos, gun_dir, mi->blob_offset[idx]);
297                 p.vel = vmd_zero_vector;                
298                 p.rad = mi->blob_radius[idx];
299                 p.type = PARTICLE_BITMAP;
300                 p.optional_data = mi->blob_anims[idx];
301                 p.attached_objnum = -1;
302                 p.attached_sig = 0;
303                 particle_create(&p);
304         }
305
306         // increment counter
307         // Num_mflash++;                
308 }
309
310 // process muzzle flash stuff
311 void mflash_process_all()
312 {
313         /*
314         mflash *mflashp;
315
316         // if the timestamp has elapsed recycle it
317         mflashp = GET_FIRST(&Mflash_used_list);
318
319         while ( mflashp!=END_OF_LIST(&Mflash_used_list) )       {                       
320                 if((mflashp->stamp == -1) || timestamp_elapsed(mflashp->stamp)){
321                         // delete it from the list!
322                         mflash *next_one = GET_NEXT(mflashp);
323
324                         // remove objp from the used list
325                         list_remove( &Mflash_used_list, mflashp );
326
327                         // add objp to the end of the free
328                         list_append( &Mflash_free_list, mflashp );
329
330                         // decrement counter
331                         Num_mflash--;
332
333                         SDL_assert(Num_mflash >= 0);
334                         
335                         mflashp = next_one;                     
336                 } else {        
337                         mflashp = GET_NEXT(mflashp);
338                 }
339         }
340         */
341 }
342
343 void mflash_render_all()
344 {
345 }
346
347 // lookup type by name
348 int mflash_lookup(char *name)
349 {       
350         int idx;
351
352         // look it up
353         for(idx=0; idx<Num_mflash_types; idx++){
354                 if(!SDL_strcasecmp(name, Mflash_info[idx].name)){
355                         return idx;
356                 }
357         }
358
359         // couldn't find it
360         return -1;      
361 }