]> icculus.org git repositories - taylor/freespace2.git/blob - src/starfield/nebula.cpp
More changes, took out a lot of the sound/* stuff which will bite later but
[taylor/freespace2.git] / src / starfield / nebula.cpp
1 /*
2  * $Logfile: /Freespace2/code/Starfield/Nebula.cpp $
3  * $Revision$
4  * $Date$
5  * $Author$
6  *
7  * Code to load & display nebulas
8  *
9  * $Log$
10  * Revision 1.2  2002/05/04 04:36:56  theoddone33
11  * More changes, took out a lot of the sound/* stuff which will bite later but
12  * I don't care.
13  *
14  * Revision 1.1.1.1  2002/05/03 03:28:10  root
15  * Initial import.
16  *
17  * 
18  * 14    9/01/99 11:26p Dave
19  * Fixed release build warnings.
20  * 
21  * 13    8/30/99 5:01p Dave
22  * Made d3d do less state changing in the nebula. Use new chat server for
23  * PXO.
24  * 
25  * 12    7/29/99 10:47p Dave
26  * Standardized D3D fogging using vertex fog. Shook out Savage 4 bugs.
27  * 
28  * 11    7/14/99 9:42a Dave
29  * Put in clear_color debug function. Put in base for 3dnow stuff / P3
30  * stuff
31  * 
32  * 10    6/22/99 7:03p Dave
33  * New detail options screen.
34  * 
35  * 9     3/31/99 8:24p Dave
36  * Beefed up all kinds of stuff, incluging beam weapons, nebula effects
37  * and background nebulae. Added per-ship non-dimming pixel colors.
38  * 
39  * 8     12/09/98 7:34p Dave
40  * Cleanup up nebula effect. Tweaked many values.
41  * 
42  * 7     12/08/98 9:36a Dave
43  * Almost done nebula effect for D3D. Looks 85% as good as Glide.
44  * 
45  * 6     12/07/98 5:51p Dave
46  * Finally got d3d fog working! Now we just need to tweak values.
47  * 
48  * 5     12/06/98 2:36p Dave
49  * Drastically improved nebula fogging.
50  * 
51  * 4     11/14/98 5:33p Dave
52  * Lots of nebula work. Put in ship contrails.
53  * 
54  * 3     11/11/98 5:37p Dave
55  * Checkin for multiplayer testing.
56  * 
57  * 2     10/07/98 10:54a Dave
58  * Initial checkin.
59  * 
60  * 1     10/07/98 10:51a Dave
61  * 
62  * 15    5/13/98 2:53p John
63  * Made subspace effect work under software.  Had to add new inner loop to
64  * tmapper.  Added glows to end of subspace effect.  Made subspace effect
65  * levels use gamepalette-subspace palette.
66  * 
67  * 14    4/10/98 5:20p John
68  * Changed RGB in lighting structure to be ubytes.  Removed old
69  * not-necessary 24 bpp software stuff.
70  * 
71  * 13    3/22/98 11:02a John
72  * Made a bunch of the detail levels actually do something
73  * 
74  * 12    2/22/98 12:19p John
75  * Externalized some strings
76  * 
77  * 11    1/23/98 5:08p John
78  * Took L out of vertex structure used B (blue) instead.   Took all small
79  * fireballs out of fireball types and used particles instead.  Fixed some
80  * debris explosion things.  Restructured fireball code.   Restructured
81  * some lighting code.   Made dynamic lighting on by default. Made groups
82  * of lasers only cast one light.  Made fireballs not cast light.
83  * 
84  * 10    1/10/98 1:14p John
85  * Added explanation to debug console commands
86  * 
87  * 9     12/21/97 4:33p John
88  * Made debug console functions a class that registers itself
89  * automatically, so you don't need to add the function to
90  * debugfunctions.cpp.  
91  * 
92  * 8     11/25/97 11:40a Hoffoss
93  * Added support for nebula placement editing.
94  * 
95  * 7     11/24/97 12:04p John
96  * 
97  * 6     11/21/97 2:55p Hoffoss
98  * Added Nebula support to Fred.  Implemented loading and saving nebula
99  * info to/from mission files.
100  * 
101  * 5     11/21/97 11:32a John
102  * Added nebulas.   Fixed some warpout bugs.
103  * 
104  * 4     11/19/97 10:47p Adam
105  * upped MAX_TRIS to 200.  Whaddya think this is, I-War?
106  * 
107  * 3     11/16/97 2:41p John
108  * added a debug function to load a nebula into the game.
109  * 
110  * 2     11/16/97 2:29p John
111  * added versioning to nebulas; put nebula code into freespace.
112  * 
113  * 1     11/16/97 1:14p John
114  *
115  * $NoKeywords: $
116  */
117
118 #include "pstypes.h"
119 #include "floating.h"
120 #include "vecmat.h"
121 #include "3d.h"
122 #include "2d.h"
123 #include "starfield.h"
124 #include "bmpman.h"
125 #include "key.h"
126 #include "freespace.h"  
127 #include "timer.h"
128 #include "nebula.h"
129 #include "palman.h"
130 #include "cfile.h"
131 #include "linklist.h"
132 #include "2d.h"
133 #include "missionparse.h"
134 #include "neb.h"
135
136 #define MAX_TRIS 200
137 #define MAX_POINTS 300
138
139 static int neb_w = 0, neb_h = 0;
140
141 static int nebula_inited = 0;
142 static int num_pts = 0;
143
144 static vector nebula_vecs[MAX_POINTS];
145 static vertex nebula_verts[MAX_POINTS];
146
147 static float scale_factor = 1.0f;
148
149 static int num_tris = 0;
150 static int tri[MAX_TRIS][3];
151
152 static int Nebula_loaded = 0;
153 static angles Nebula_pbh;
154 static matrix Nebula_orient;
155
156 int Nebula_pitch;
157 int Nebula_bank;
158 int Nebula_heading;
159
160 void nebula_close()
161 {
162         if (!Nebula_loaded) return;
163
164         Nebula_loaded = 0;
165 }
166
167 #define NEBULA_FILE_ID NOX("NEBU")
168 #define NEBULA_MAJOR_VERSION 1          // Can be 1-?
169 #define NEBULA_MINOR_VERSION 0          // Can be 0-99
170
171 // given:
172 // u,v in range 0-1
173
174 void project_2d_onto_sphere( vector *pnt, float u, float v )
175 {
176         float a,x,y,z,s;
177
178         a = PI * (2.0f * u - 1.0f );
179         z = 2.0f * v - 1.0f;    
180         s = scale_factor * fl_sqrt( 1.0f - z*z );
181         x = s * (float)cos(a);
182         y = s * (float)sin(a);
183         pnt->x = x;
184         pnt->y = y;
185         pnt->z = z;
186 }
187
188 // Version 199 mean major version=1, minor=99.
189 // Changing major means no longer compatible.
190 // Revision history:
191 // 1.00 - initial version
192
193 // returns 0 if failed
194 int load_nebula_sub(char *filename)
195 {
196         CFILE *fp;
197         char id[16];
198         int version, major, minor;
199
200         fp = cfopen(filename, "rb");
201
202         if ( !fp )      {
203                 return 0;
204         }
205
206         // ID of NEBU
207         cfread( id, 4, 1, fp ); 
208         if ( strncmp( id, NEBULA_FILE_ID, 4))   {
209                 mprintf(( "Not a valid nebula file.\n" ));
210                 return 0;
211         } 
212         cfread( &version, sizeof(int), 1, fp );
213         major = version / 100;
214         minor = version % 100;
215
216         if ( major != NEBULA_MAJOR_VERSION )    {
217                 mprintf(( "An out of date nebula file.\n" ));
218                 return 0;
219         }       
220
221         cfread( &num_pts, sizeof(int), 1, fp );
222         Assert( num_pts < MAX_POINTS );
223         cfread( &num_tris, sizeof(int), 1, fp );
224         Assert( num_tris < MAX_TRIS );
225
226         for (int i=0; i<num_pts; i++ )  {
227                 float xf, yf;
228                 int l;
229
230                 cfread( &xf, sizeof(float), 1, fp );
231                 cfread( &yf, sizeof(float), 1, fp );
232                 cfread( &l, sizeof(int), 1, fp );
233                 project_2d_onto_sphere( &nebula_vecs[i], 1.0f - xf, yf );
234                 vm_vec_scale( &nebula_vecs[i], 10.0f );
235                 nebula_verts[i].b = ubyte((l*255)/31);
236
237                 // throw in some randomness to the nebula vertices depth
238         }
239
240         for (int i=0; i<num_tris; i++ ) {
241                 cfread( &tri[i][0], sizeof(int), 1, fp );
242                 cfread( &tri[i][1], sizeof(int), 1, fp );
243                 cfread( &tri[i][2], sizeof(int), 1, fp );
244         }
245
246         cfclose(fp);
247
248         return 1;
249 }
250
251 void nebula_init( char *filename, int pitch, int bank, int heading )
252 {
253         angles a;
254
255         a.p = ANG_TO_RAD((float) pitch);
256         a.b = ANG_TO_RAD((float) bank);
257         a.h = ANG_TO_RAD((float) heading);
258         nebula_init(filename, &a);
259 }
260
261 void nebula_init( char *filename, angles * pbh )
262 {
263         if ( Nebula_loaded )    {
264                 nebula_close();
265         }
266
267         if ( load_nebula_sub( cf_add_ext(filename, NOX(".neb")) ) ) {
268                 Nebula_loaded = 1;
269         }
270
271         if ( pbh ) {
272                 Nebula_pbh = *pbh;
273                 vm_angles_2_matrix(&Nebula_orient, &Nebula_pbh );
274
275         } else {
276                 Nebula_pbh.p = 0.0f;
277                 Nebula_pbh.b = 0.0f;
278                 Nebula_pbh.h = 0.0f;
279                 Nebula_orient = vmd_identity_matrix;
280         }
281 }
282
283 void nebula_render()
284 {
285         int i;
286         // int r, g, b;
287
288         // no nebula for you!
289         return;
290
291         if ( !Nebula_loaded ) {
292                 return;
293         }
294
295         if ( !Detail.planets_suns )     {
296                 return;
297         }       
298
299         // Rotate the nebula.
300         g3_start_instance_matrix( NULL, &Nebula_orient );
301
302         for (i=0; i<num_pts; i++ )      {
303                 g3_rotate_faraway_vertex( &nebula_verts[i], &nebula_vecs[i] );
304                 g3_project_vertex( &nebula_verts[i] );
305         }
306
307         int saved_gr_zbuffering =       gr_zbuffer_get();
308
309         gr_zbuffer_set(GR_ZBUFF_NONE);
310
311         for (i=0; i<num_tris; i++ ) {
312
313                 vertex * verts[3];
314
315                 verts[0] = &nebula_verts[tri[i][0]];
316                 verts[1] = &nebula_verts[tri[i][1]];
317                 verts[2] = &nebula_verts[tri[i][2]];
318
319                 g3_draw_poly(3, verts, TMAP_FLAG_RAMP | TMAP_FLAG_GOURAUD | TMAP_FLAG_NEBULA );
320         }               
321
322         g3_done_instance();
323
324         gr_zbuffer_set(saved_gr_zbuffering);
325
326         // always switch off fogging for good measure
327         if((The_mission.flags & MISSION_FLAG_FULLNEB) && (Neb2_render_mode == NEB2_RENDER_NONE)){
328                 gr_fog_set(GR_FOGMODE_NONE, 0, 0, 0);
329         }
330 }
331
332 DCF(nebula,"Loads a different nebula")
333 {
334         if ( Dc_command )       {
335                 dc_get_arg(ARG_STRING|ARG_NONE);
336                 if ( Dc_arg_type == ARG_NONE )  {
337                         nebula_close();
338                 } else {
339                         nebula_init( Dc_arg );
340                 }
341         }
342         if ( Dc_help )  {
343                 dc_printf( "Usage: nebula filename\nLoads the nebula file. No filename takes away nebula\n" );
344         }       
345 }
346
347
348