2 * Copyright (C) Volition, Inc. 1999. All rights reserved.
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
10 * $Logfile: /Freespace2/code/Weapon/MuzzleFlash.cpp $
15 * all sorts of cool stuff about ships
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
25 * Revision 1.3 2002/06/09 04:41:29 relnev
26 * added copyright header
28 * Revision 1.2 2002/05/07 03:16:53 theoddone33
29 * The Great Newline Fix
31 * Revision 1.1.1.1 2002/05/03 03:28:11 root
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.
39 * 6 5/18/99 1:30p Dave
40 * Added muzzle flash table stuff.
42 * 5 4/25/99 3:02p Dave
43 * Build defines for the E3 build.
45 * 4 4/12/99 11:03p Dave
46 * Removed contrails and muzzle flashes from MULTIPLAYER_BETA builds.
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.
52 * 2 1/08/99 2:08p Dave
53 * Fixed software rendering for pofview. Super early support for AWACS and
62 #include "systemvars.h"
65 #include "muzzleflash.h"
69 // ---------------------------------------------------------------------------------------------------------------------
70 // MUZZLE FLASH DEFINES/VARS
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
84 mflash_info Mflash_info[MAX_MUZZLE_FLASH_TYPES];
85 int Num_mflash_types = 0;
89 // Stuff for missile trails doesn't need to be saved or restored... or does it?
91 typedef struct mflash {
95 ubyte type; // muzzle flash type
96 int blobs[MAX_MFLASH_BLOBS]; // blobs
100 mflash Mflash[MAX_MFLASH];
102 mflash Mflash_free_list;
103 mflash Mflash_used_list;
106 // ---------------------------------------------------------------------------------------------------------------------
107 // MUZZLE FLASH FUNCTIONS
110 // initialize muzzle flash stuff for the whole game
111 void mflash_game_init()
116 char name[MAX_MFLASH_NAME_LEN];
117 float offset, radius;
121 read_file_text("mflash.tbl");
125 required_string("#Muzzle flash types");
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++];
135 memset(m, 0, sizeof(mflash_info));
136 for(idx=0; idx<MAX_MFLASH_BLOBS; idx++){
137 m->blob_anims[idx] = -1;
140 required_string("+name:");
141 stuff_string(m->name, F_NAME, NULL);
145 while(optional_string("+blob_name:")){
146 stuff_string(name, F_NAME, NULL, MAX_MFLASH_NAME_LEN);
148 required_string("+blob_offset:");
149 stuff_float(&offset);
151 required_string("+blob_radius:");
152 stuff_float(&radius);
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;
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);
171 // hardcoded FS1 values
175 Num_mflash_types = 0;
176 m = &Mflash_info[Num_mflash_types++];
178 memset(m, 0, sizeof(mflash_info));
180 for (idx=0; idx<MAX_MFLASH_BLOBS; idx++) {
181 m->blob_anims[idx] = -1;
184 SDL_strlcpy(m->name, "mflash_small", MAX_MFLASH_NAME_LEN);
187 SDL_assert(m->num_blobs <= MAX_MFLASH_BLOBS);
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;
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;
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;
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;
211 // initialize muzzle flash stuff for the level
212 void mflash_level_init()
219 list_init( &Mflash_free_list );
220 list_init( &Mflash_used_list );
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] );
230 for(i=0; i<Num_mflash_types; i++){
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);
240 // shutdown stuff for the level
241 void mflash_level_close()
245 // create a muzzle flash on the guy
246 void mflash_create(vector *gun_pos, vector *gun_dir, int mflash_type)
253 // standalone server should never create trails
254 if(Game_mode & GM_STANDALONE_SERVER){
259 if((mflash_type >= Num_mflash_types) || (mflash_type < 0)){
264 if (Num_mflash >= MAX_MFLASH ) {
266 mprintf(("Muzzle flash creation failed - too many trails!\n" ));
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
275 // remove trailp from the free list
276 list_remove( &Mflash_free_list, mflashp );
278 // insert trailp onto the end of used list
279 list_append( &Mflash_used_list, mflashp );
282 mflashp->type = (ubyte)mflash_type;
285 // create the actual animations
286 mi = &Mflash_info[mflash_type];
287 for(idx=0; idx<mi->num_blobs; idx++){
290 if(mi->blob_anims[idx] < 0){
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;
310 // process muzzle flash stuff
311 void mflash_process_all()
316 // if the timestamp has elapsed recycle it
317 mflashp = GET_FIRST(&Mflash_used_list);
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);
324 // remove objp from the used list
325 list_remove( &Mflash_used_list, mflashp );
327 // add objp to the end of the free
328 list_append( &Mflash_free_list, mflashp );
333 SDL_assert(Num_mflash >= 0);
337 mflashp = GET_NEXT(mflashp);
343 void mflash_render_all()
347 // lookup type by name
348 int mflash_lookup(char *name)
353 for(idx=0; idx<Num_mflash_types; idx++){
354 if(!SDL_strcasecmp(name, Mflash_info[idx].name)){