FS2_Open
Open source remastering of the Freespace 2 engine
starfield.cpp
Go to the documentation of this file.
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 the
6  * source.
7  *
8 */
9 
10 
11 
12 #include <limits.h>
13 
14 #include "cmdline/cmdline.h"
15 #include "debugconsole/console.h"
16 #include "freespace2/freespace.h"
17 #include "hud/hud.h"
18 #include "hud/hudtarget.h"
19 #include "io/timer.h"
20 #include "lighting/lighting.h"
21 #include "math/vecmat.h"
22 #include "mission/missionparse.h"
23 #include "model/modelrender.h"
24 #include "nebula/neb.h"
25 #include "parse/parselo.h"
26 #include "render/3d.h"
27 #include "starfield/nebula.h"
28 #include "starfield/starfield.h"
29 #include "starfield/supernova.h"
30 
31 #define MAX_DEBRIS_VCLIPS 4
32 #define DEBRIS_ROT_MIN 10000
33 #define DEBRIS_ROT_RANGE 8
34 #define DEBRIS_ROT_RANGE_SCALER 10000
35 #define RND_MAX_MASK 0x3fff
36 #define HALF_RND_MAX 0x2000
37 
38 typedef struct {
41  int active;
42  int vclip;
43  float size;
44 } old_debris;
45 
46 const int MAX_DEBRIS = 200;
47 const int MAX_STARS = 2000;
48 const float MAX_DIST = 50.0f;
49 const float MAX_DIST_RANGE = 60.0f;
50 const float MIN_DIST_RANGE = 14.0f;
51 const float BASE_SIZE = 0.12f;
52 float BASE_SIZE_NEB = 0.5f;
53 
54 static int Subspace_model_inner = -1;
55 static int Subspace_model_outer = -1;
56 static int Rendering_to_env = 0;
57 
58 int Num_stars = 500;
60 
61 #define MAX_FLARE_COUNT 10
62 #define MAX_FLARE_BMP 6
63 
64 typedef struct flare_info {
65  float pos;
66  float scale;
67  int tex_num;
68 } flare_info;
69 
70 typedef struct flare_bitmap {
72  int bitmap_id;
73 } flare_bitmap;
74 
75 
76 // global info (not individual instances)
77 typedef struct starfield_bitmap {
78  char filename[MAX_FILENAME_LEN]; // bitmap filename
79  char glow_filename[MAX_FILENAME_LEN]; // only for suns
80  int bitmap_id; // bitmap handle
81  int n_frames;
82  int fps;
83  int glow_bitmap; // only for suns
85  int glow_fps;
86  int xparent;
87  float r, g, b, i, spec_r, spec_g, spec_b; // only for suns
88  int glare; // only for suns
89  int flare; // Is there a lens-flare for this sun?
90  flare_info flare_infos[MAX_FLARE_COUNT]; // each flare can use a texture in flare_bmp, with different scale
91  flare_bitmap flare_bitmaps[MAX_FLARE_BMP]; // bitmaps for different lens flares (can be re-used)
92  int n_flares; // number of flares actually used
93  int n_flare_bitmaps; // number of flare bitmaps available
95  int preload;
97 
98 // starfield bitmap instance
99 typedef struct starfield_bitmap_instance {
100  float scale_x, scale_y; // x and y scale
101  int div_x, div_y; // # of x and y divisions
102  angles ang; // angles from FRED
103  int star_bitmap_index; // index into starfield_bitmap array
104  int n_verts;
106 
107  starfield_bitmap_instance() : scale_x(1.0f), scale_y(1.0f), div_x(1), div_y(1), star_bitmap_index(0), n_verts(0), verts(NULL) {
108  ang.p = 0.0f;
109  ang.b = 0.0f;
110  ang.h = 0.0f;
111  }
113 
114 // for drawing cool stuff on the background - comes from a table
115 static SCP_vector<starfield_bitmap> Starfield_bitmaps;
116 static SCP_vector<starfield_bitmap_instance> Starfield_bitmap_instances;
117 
118 // sun bitmaps and sun glow bitmaps
119 static SCP_vector<starfield_bitmap> Sun_bitmaps;
121 
122 // Goober5000
124 int Cur_background = -1;
126 
130 
131 typedef struct star {
135 } star;
136 
137 typedef struct vDist {
138  int x;
139  int y;
140 } vDist;
141 
143 
145 
146 
147 typedef struct debris_vclip {
148  int bm;
149  int nframes;
151 } debris_vclip;
155 
156 //XSTR:OFF
157 debris_vclip Debris_vclips_normal[MAX_DEBRIS_VCLIPS] = { { -1, -1, "debris01" }, { -1, -1, "debris02" }, { -1, -1, "debris03" }, { -1, -1, "debris04" } };
158 debris_vclip Debris_vclips_nebula[MAX_DEBRIS_VCLIPS] = { { -1, -1, "nebdeb01" }, { -1, -1, "nebdeb02" }, { -1, -1, "nebdeb03" }, { -1, -1, "nebdeb04" } };
160 //XSTR:ON
161 
162 int stars_debris_loaded = 0; // 0 = not loaded, 1 = normal vclips, 2 = nebula vclips
163 
164 // background data
165 int Stars_background_inited = 0; // if we're inited
166 int Nmodel_num = -1; // model num
167 int Nmodel_instance_num = -1; // model instance num
168 matrix Nmodel_orient = IDENTITY_MATRIX; // model orientation
169 int Nmodel_flags = DEFAULT_NMODEL_FLAGS; // model flags
170 int Nmodel_bitmap = -1; // model texture
171 
174 
175 bool Dynamic_environment = false;
177 
179 {
180  int i;
181 
182  if (vclips == NULL)
183  return;
184 
185  for (i = 0; i < MAX_DEBRIS_VCLIPS; i++) {
186  if ( (vclips[i].bm >= 0) && bm_release(vclips[i].bm) ) {
187  vclips[i].bm = -1;
188  vclips[i].nframes = -1;
189  }
190  }
191 }
192 
194 {
195  int i;
196 
197  if (vclips == NULL) {
198  Int3();
199  return;
200  }
201 
202  for (i = 0; i < MAX_DEBRIS_VCLIPS; i++) {
203  vclips[i].bm = bm_load_animation( vclips[i].name, &vclips[i].nframes, NULL, NULL, 1 );
204 
205  if ( vclips[i].bm < 0 ) {
206  // try loading it as a single bitmap
207  vclips[i].bm = bm_load(Debris_vclips[i].name);
208  vclips[i].nframes = 1;
209 
210  if (vclips[i].bm <= 0) {
211  Error( LOCATION, "Couldn't load animation/bitmap '%s'\n", vclips[i].name );
212  }
213  }
214  }
215 }
216 
217 void stars_load_debris(int fullneb = 0)
218 {
220  return;
221  }
222 
223  // if we're in nebula mode
224  if ( fullneb && (stars_debris_loaded != 2) ) {
225  stars_release_debris_vclips(Debris_vclips);
226  stars_load_debris_vclips(Debris_vclips_nebula);
227  Debris_vclips = Debris_vclips_nebula;
229  } else if (stars_debris_loaded != 1) {
230  stars_release_debris_vclips(Debris_vclips);
231  stars_load_debris_vclips(Debris_vclips_normal);
232  Debris_vclips = Debris_vclips_normal;
234  }
235 }
236 
238 const float p_phi = 10.0f, p_theta = 10.0f;
239 
240 extern void stars_project_2d_onto_sphere( vec3d *pnt, float rho, float phi, float theta );
241 
242 static void starfield_create_bitmap_buffer(const int si_idx)
243 {
246 
247  vertex v[4];
248  matrix m, m_bank;
249  int idx, s_idx;
250  float ui, vi;
251  angles bank_first;
252 
253  starfield_bitmap_instance *sbi = &Starfield_bitmap_instances[si_idx];
254 
255  angles *a = &sbi->ang;
256  float scale_x = sbi->scale_x;
257  float scale_y = sbi->scale_y;
258  int div_x = sbi->div_x;
259  int div_y = sbi->div_y;
260 
261  // cap division values
262 // div_x = div_x > MAX_PERSPECTIVE_DIVISIONS ? MAX_PERSPECTIVE_DIVISIONS : div_x;
263  div_x = 1;
264  div_y = div_y > MAX_PERSPECTIVE_DIVISIONS ? MAX_PERSPECTIVE_DIVISIONS : div_y;
265 
266  if (sbi->verts != NULL) {
267  delete [] sbi->verts;
268  }
269 
270  sbi->verts = new(std::nothrow) vertex[div_x * div_y * 6];
271 
272  if (sbi->verts == NULL) {
273  sbi->star_bitmap_index = -1;
274  return;
275  }
276 
277  sbi->n_verts = div_x * div_y * 6;
278 
279  // texture increment values
280  ui = 1.0f / (float)div_x;
281  vi = 1.0f / (float)div_y;
282 
283  // adjust for aspect ratio
284  //scale_x *= (gr_screen.clip_aspect + 0.55f); // fudge factor
285  //scale_x *= (gr_screen.clip_aspect + (0.7333333f/gr_screen.clip_aspect)); // fudge factor
286  scale_x *= 1.883333f; //fudge factor
287 
288  float s_phi = 0.5f + (((p_phi * scale_x) / 360.0f) / 2.0f);
289  float s_theta = (((p_theta * scale_y) / 360.0f) / 2.0f);
290  float d_phi = -(((p_phi * scale_x) / 360.0f) / (float)(div_x));
291  float d_theta = -(((p_theta * scale_y) / 360.0f) / (float)(div_y));
292 
293  // bank matrix
294  bank_first.p = 0.0f;
295  bank_first.b = a->b;
296  bank_first.h = 0.0f;
297  vm_angles_2_matrix(&m_bank, &bank_first);
298 
299  // convert angles to matrix
300  angles a_temp = *a;
301  a_temp.b = 0.0f;
302  vm_angles_2_matrix(&m, &a_temp);
303 
304  // generate the bitmap points
305  for(idx=0; idx<=div_x; idx++) {
306  for(s_idx=0; s_idx<=div_y; s_idx++) {
307  // get world spherical coords
308  stars_project_2d_onto_sphere(&s_points[idx][s_idx], 1000.0f, s_phi + ((float)idx*d_phi), s_theta + ((float)s_idx*d_theta));
309 
310  // bank the bitmap first
311  vm_vec_rotate(&t_points[idx][s_idx], &s_points[idx][s_idx], &m_bank);
312 
313  // rotate on the sphere
314  vm_vec_rotate(&s_points[idx][s_idx], &t_points[idx][s_idx], &m);
315  }
316  }
317 
318  memset(v, 0, sizeof(vertex) * 4);
319 
320  int j = 0;
321 
322  vertex *verts = sbi->verts;
323 
324  for (idx = 0; idx < div_x; idx++) {
325  for (s_idx = 0; s_idx < div_y; s_idx++) {
326  // stuff texture coords
327  v[0].texture_position.u = ui * float(idx);
328  v[0].texture_position.v = vi * float(s_idx);
329 
330  v[1].texture_position.u = ui * float(idx+1);
331  v[1].texture_position.v = vi * float(s_idx);
332 
333  v[2].texture_position.u = ui * float(idx+1);
334  v[2].texture_position.v = vi * float(s_idx+1);
335 
336  v[3].texture_position.u = ui * float(idx);
337  v[3].texture_position.v = vi * float(s_idx+1);
338 
339  g3_transfer_vertex(&v[0], &s_points[idx][s_idx]);
340  g3_transfer_vertex(&v[1], &s_points[idx+1][s_idx]);
341  g3_transfer_vertex(&v[2], &s_points[idx+1][s_idx+1]);
342  g3_transfer_vertex(&v[3], &s_points[idx][s_idx+1]);
343 
344  // poly 1
345  verts[j++] = v[0];
346  verts[j++] = v[1];
347  verts[j++] = v[2];
348  // poly 2
349  verts[j++] = v[0];
350  verts[j++] = v[2];
351  verts[j++] = v[3];
352  }
353  }
354 
355  Assert( j == sbi->n_verts );
356 }
357 
358 // take the Starfield_bitmap_instances[] and make all the vertex buffers that you'll need to draw it
359 static void starfield_generate_bitmap_buffers()
360 {
361  int idx;
362 
363  int sb_instances = (int)Starfield_bitmap_instances.size();
364 
365  for (idx = 0; idx < sb_instances; idx++) {
366  if (Starfield_bitmap_instances[idx].star_bitmap_index < 0) {
367  continue;
368  }
369 
370  starfield_create_bitmap_buffer(idx);
371  }
372 }
373 
374 static void starfield_bitmap_entry_init(starfield_bitmap *sbm)
375 {
376  int i;
377 
378  Assert( sbm != NULL );
379 
380  memset( sbm, 0, sizeof(starfield_bitmap) );
381 
382  sbm->bitmap_id = -1;
383  sbm->glow_bitmap = -1;
384  sbm->glow_n_frames = 1;
385 
386  for (i = 0; i < MAX_FLARE_BMP; i++) {
387  sbm->flare_bitmaps[i].bitmap_id = -1;
388  }
389 
390  for (i = 0; i < MAX_FLARE_COUNT; i++) {
391  sbm->flare_infos[i].tex_num = -1;
392  }
393 }
394 
395 #define CHECK_END() { \
396  if (in_check) { \
397  required_string("#end"); \
398  in_check = false; \
399  run_count = 0; \
400  } \
401 }
402 
403 void parse_startbl(const char *filename)
404 {
405  char name[MAX_FILENAME_LEN], tempf[16];
406  starfield_bitmap sbm;
407  int idx;
408  bool in_check = false;
409  int rc = -1;
410  int run_count = 0;
411 
412  try
413  {
414  read_file_text(filename, CF_TYPE_TABLES);
415  reset_parse();
416 
417  // freaky! ;)
418  while (!check_for_eof()) {
419  while ((rc = optional_string_either("$Bitmap:", "$BitmapX:")) != -1) {
420  in_check = true;
421 
422  starfield_bitmap_entry_init(&sbm);
423 
425  sbm.xparent = rc; // 0 == intensity alpha bitmap, 1 == green xparency bitmap
426 
427  if ((idx = stars_find_bitmap(sbm.filename)) >= 0) {
428  if (sbm.xparent == Starfield_bitmaps[idx].xparent) {
430  Warning(LOCATION, "Starfield bitmap '%s' listed more than once!! Only using the first entry!", sbm.filename);
431  }
432  else {
433  Warning(LOCATION, "Starfield bitmap '%s' already listed as a %s bitmap!! Only using the xparent version!",
434  sbm.filename, (rc) ? "xparent" : "non-xparent");
435  }
436  }
437  else {
438  Starfield_bitmaps.push_back(sbm);
439  }
440  }
441 
442  CHECK_END();
443 
444  while (optional_string("$Sun:")) {
445  in_check = true;
446 
447  starfield_bitmap_entry_init(&sbm);
448 
450 
451  // associated glow
452  required_string("$Sunglow:");
454 
455  // associated lighting values
456  required_string("$SunRGBI:");
457  stuff_float(&sbm.r);
458  stuff_float(&sbm.g);
459  stuff_float(&sbm.b);
460  stuff_float(&sbm.i);
461 
462  if (optional_string("$SunSpecularRGB:")) {
463  stuff_float(&sbm.spec_r);
464  stuff_float(&sbm.spec_g);
465  stuff_float(&sbm.spec_b);
466  }
467  else {
468  sbm.spec_r = sbm.r;
469  sbm.spec_g = sbm.g;
470  sbm.spec_b = sbm.b;
471  }
472 
473  // lens flare stuff
474  if (optional_string("$Flare:")) {
475  sbm.flare = 1;
476 
477  required_string("+FlareCount:");
478  stuff_int(&sbm.n_flares);
479 
480  // if there's a flare, it has to have at least one texture
481  required_string("$FlareTexture1:");
483 
484  sbm.n_flare_bitmaps = 1;
485 
486  for (idx = 1; idx < MAX_FLARE_BMP; idx++) {
487  // allow 9999 textures (theoretically speaking, that is)
488  sprintf(tempf, "$FlareTexture%d:", idx + 1);
489 
490  if (optional_string(tempf)) {
491  sbm.n_flare_bitmaps++;
493  }
494  // else break; //don't allow flaretexture1 and then 3, etc.
495  }
496 
497  required_string("$FlareGlow1:");
498 
499  required_string("+FlareTexture:");
500  stuff_int(&sbm.flare_infos[0].tex_num);
501 
502  required_string("+FlarePos:");
503  stuff_float(&sbm.flare_infos[0].pos);
504 
505  required_string("+FlareScale:");
506  stuff_float(&sbm.flare_infos[0].scale);
507 
508  sbm.n_flares = 1;
509 
510  for (idx = 1; idx < MAX_FLARE_COUNT; idx++) {
511  // allow a lot of glows
512  sprintf(tempf, "$FlareGlow%d:", idx + 1);
513 
514  if (optional_string(tempf)) {
515  sbm.n_flares++;
516 
517  required_string("+FlareTexture:");
518  stuff_int(&sbm.flare_infos[idx].tex_num);
519 
520  required_string("+FlarePos:");
521  stuff_float(&sbm.flare_infos[idx].pos);
522 
523  required_string("+FlareScale:");
524  stuff_float(&sbm.flare_infos[idx].scale);
525  }
526  // else break; //don't allow "flare 1" and then "flare 3"
527  }
528  }
529 
530  sbm.glare = !optional_string("$NoGlare:");
531 
532  sbm.xparent = 1;
533 
534  if ((idx = stars_find_sun(sbm.filename)) >= 0) {
536  Sun_bitmaps[idx] = sbm;
537  else
538  Warning(LOCATION, "Sun bitmap '%s' listed more than once!! Only using the first entry!", sbm.filename);
539  }
540  else {
541  Sun_bitmaps.push_back(sbm);
542  }
543  }
544 
545  CHECK_END();
546 
547  // normal debris pieces
548  while (optional_string("$Debris:")) {
549  in_check = true;
550 
552 
554  strcpy_s(Debris_vclips_normal[Num_debris_normal++].name, name);
555  }
556  else {
557  Warning(LOCATION, "Could not load normal motion debris '%s'; maximum of %d exceeded.", name, MAX_DEBRIS_VCLIPS);
558  }
559  }
560 
561  CHECK_END();
562 
563  // nebula debris pieces
564  while (optional_string("$DebrisNeb:")) {
565  in_check = true;
566 
568 
570  strcpy_s(Debris_vclips_nebula[Num_debris_nebula++].name, name);
571  }
572  else {
573  Warning(LOCATION, "Could not load nebula motion debris '%s'; maximum of %d exceeded.", name, MAX_DEBRIS_VCLIPS);
574  }
575  }
576 
577  CHECK_END();
578 
579  // since it's possible for some idiot to have a tbl screwed up enough
580  // that this ends up in an endless loop, give an opportunity to advance
581  // through the file no matter what, because even the retail tbl has an
582  // extra "#end" line in it.
583  if (optional_string("#end") || (run_count++ > 5)) {
584  run_count = 0;
585  advance_to_eoln(NULL);
586  }
587  }
588  }
589  catch (const parse::ParseException& e)
590  {
591  mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
592  return;
593  }
594 }
595 
597 {
598  int idx, i;
599  starfield_bitmap *sb = NULL;
600  static int Star_bitmaps_loaded = 0;
601 
602  if (Star_bitmaps_loaded)
603  return;
604 
605  // pre-load all starfield bitmaps. ONLY SHOULD DO THIS FOR FRED!!
606  // this can get nasty when a lot of bitmaps are in use so spare it for
607  // the normal game and only do this in FRED
608  int mprintf_count = 0;
609  for (idx = 0; idx < (int)Starfield_bitmaps.size(); idx++) {
610  sb = &Starfield_bitmaps[idx];
611 
612  if (sb->bitmap_id < 0) {
613  sb->bitmap_id = bm_load(sb->filename);
614 
615  // maybe didn't load a static image so try for an animated one
616  if (sb->bitmap_id < 0) {
617  sb->bitmap_id = bm_load_animation(sb->filename, &sb->n_frames, &sb->fps, NULL, 1);
618 
619  if (sb->bitmap_id < 0) {
620  mprintf(("Unable to load starfield bitmap: '%s'!\n", sb->filename));
621  mprintf_count++;
622  }
623  }
624  }
625  }
626  if (mprintf_count > 0) {
627  Warning(LOCATION, "Unable to load %d starfield bitmap(s)!\n", mprintf_count);
628  }
629 
630  for (idx = 0; idx < (int)Sun_bitmaps.size(); idx++) {
631  sb = &Sun_bitmaps[idx];
632 
633  // normal bitmap
634  if (sb->bitmap_id < 0) {
635  sb->bitmap_id = bm_load(sb->filename);
636 
637  // maybe didn't load a static image so try for an animated one
638  if (sb->bitmap_id < 0) {
639  sb->bitmap_id = bm_load_animation(sb->filename, &sb->n_frames, &sb->fps, NULL, 1);
640 
641  if (sb->bitmap_id < 0) {
642  Warning(LOCATION, "Unable to load sun bitmap: '%s'!\n", sb->filename);
643  }
644  }
645  }
646 
647  // glow bitmap
648  if (sb->glow_bitmap < 0) {
649  sb->glow_bitmap = bm_load(sb->glow_filename);
650 
651  // maybe didn't load a static image so try for an animated one
652  if (sb->glow_bitmap < 0) {
653  sb->glow_bitmap = bm_load_animation(sb->glow_filename, &sb->glow_n_frames, &sb->glow_fps, NULL, 1);
654 
655  if (sb->glow_bitmap < 0) {
656  Warning(LOCATION, "Unable to load sun glow bitmap: '%s'!\n", sb->glow_filename);
657  }
658  }
659  }
660 
661  if (sb->flare) {
662  for (i = 0; i < MAX_FLARE_BMP; i++) {
663  if ( !strlen(sb->flare_bitmaps[i].filename) )
664  continue;
665 
666  if (sb->flare_bitmaps[i].bitmap_id < 0) {
668 
669  if (sb->flare_bitmaps[i].bitmap_id < 0) {
670  Warning(LOCATION, "Unable to load sun flare bitmap: '%s'!\n", sb->flare_bitmaps[i].filename);
671  continue;
672  }
673  }
674  }
675  }
676  }
677 
678  Star_bitmaps_loaded = 1;
679 }
680 
682 {
683  for (uint i = 0; i < Starfield_bitmap_instances.size(); i++) {
684  delete [] Starfield_bitmap_instances[i].verts;
685  Starfield_bitmap_instances[i].verts = NULL;
686  }
687 
688  Starfield_bitmap_instances.clear();
689  Suns.clear();
690 }
691 
692 // call on game startup
694 {
695  // starfield bitmaps
696  Num_debris_normal = 0;
697  Num_debris_nebula = 0;
698 
699  // parse stars.tbl
700  parse_startbl("stars.tbl");
701 
702  parse_modular_table("*-str.tbm", parse_startbl);
703 }
704 
705 // call only from game_shutdown()!!
707 {
709 
710  // any other code goes here
711 }
712 
713 // called before mission parse so we can clear out all of the old stuff
714 void stars_pre_level_init(bool clear_backgrounds)
715 {
716  uint idx, i;
717  starfield_bitmap *sb = NULL;
718 
719  if (clear_backgrounds)
720  {
721  // Goober5000 - clear entire array, including backgrounds that will be unused
722  for (i = 0; i < MAX_BACKGROUNDS; i++)
723  {
724  Backgrounds[i].suns.clear();
725  Backgrounds[i].bitmaps.clear();
726  }
727  }
728 
730 
731  stars_set_background_model(NULL, NULL);
733 
734  // mark all starfield and sun bitmaps as unused for this mission and release any current bitmaps
735  // NOTE: that because of how we have to load the bitmaps it's important to release all of
736  // them first thing rather than after we have marked and loaded only what's needed
737  // NOTE2: there is a reason that we don't check for release before setting the handle to -1 so
738  // be aware that this is NOT a bug. also, bmpman should NEVER return 0 as a valid handle!
739  if ( !Fred_running ) {
740  for (idx = 0; idx < Starfield_bitmaps.size(); idx++) {
741  sb = &Starfield_bitmaps[idx];
742 
743  if (sb->bitmap_id > 0) {
744  bm_release(sb->bitmap_id);
745  sb->bitmap_id = -1;
746  }
747 
748  sb->used_this_level = 0;
749  sb->preload = 0;
750  }
751 
752  for (idx = 0; idx < Sun_bitmaps.size(); idx++) {
753  sb = &Sun_bitmaps[idx];
754 
755  if (sb->bitmap_id > 0) {
756  bm_release(sb->bitmap_id);
757  sb->bitmap_id = -1;
758  }
759 
760  if (sb->glow_bitmap > 0) {
761  bm_release(sb->glow_bitmap);
762  sb->glow_bitmap = -1;
763  }
764 
765  for (i = 0; i < MAX_FLARE_BMP; i++) {
766  if (sb->flare_bitmaps[i].bitmap_id > 0) {
768  sb->flare_bitmaps[i].bitmap_id = -1;
769  }
770  }
771 
772  sb->used_this_level = 0;
773  sb->preload = 0;
774  }
775  }
776 
777  Dynamic_environment = false;
778  Motion_debris_override = false;
779 }
780 
781 // call this in game_post_level_init() so we know whether we're running in full nebula mode or not
783 {
784  int i;
785  vec3d v;
786  float dist, dist_max;
787  ubyte red,green,blue,alpha;
788 
789 
792 
794 
795 // following code randomly distributes star points within a sphere volume, which
796 // avoids there being denser areas along the edges and in corners that we had in the
797 // old rectangular distribution scheme.
798  dist_max = (float) (HALF_RND_MAX * HALF_RND_MAX);
799  for (i=0; i<MAX_STARS; i++) {
800  dist = dist_max;
801  while (dist >= dist_max) {
802  v.xyz.x = (float) ((myrand() & RND_MAX_MASK) - HALF_RND_MAX);
803  v.xyz.y = (float) ((myrand() & RND_MAX_MASK) - HALF_RND_MAX);
804  v.xyz.z = (float) ((myrand() & RND_MAX_MASK) - HALF_RND_MAX);
805 
806  dist = v.xyz.x * v.xyz.x + v.xyz.y * v.xyz.y + v.xyz.z * v.xyz.z;
807  }
808  vm_vec_copy_normalize(&Stars[i].pos, &v);
809 
810  {
811  red= (ubyte)(myrand() % 63 +192); //192-255
812  green= (ubyte)(myrand() % 63 +192); //192-255
813  blue= (ubyte)(myrand() % 63 +192); //192-255
814  alpha = (ubyte)(myrand () % 192 + 24); //24-216
815 
816  gr_init_alphacolor(&Stars[i].col, red, green, blue, alpha, AC_TYPE_BLEND);
817  }
818 
819  }
820 
821  memset( &odebris, 0, sizeof(old_debris) * MAX_DEBRIS );
822 
823 
824  for (i=0; i<8; i++ ) {
825  ubyte intensity = (ubyte)((i + 1) * 24);
826  gr_init_alphacolor(&star_aacolors[i], 255, 255, 255, intensity, AC_TYPE_BLEND );
827  gr_init_color(&star_colors[i], intensity, intensity, intensity );
828  }
829 
830  last_stars_filled = 0;
831 
832  // if we have no sun instances, create one
833  if ( !Suns.size() ) {
834  if ( !strlen(Sun_bitmaps[0].filename) ) {
835  mprintf(("Trying to add default sun but no default exists!!\n"));
836  } else {
837  mprintf(("Adding default sun.\n"));
838 
840 
841  // stuff some values
842  def_sun.ang.h = fl_radians(60.0f);
843 
844  Suns.push_back(def_sun);
845  }
846  }
847 
848  // FRED doesn't do normal page_in stuff so we need to load up the bitmaps here instead
849  if (Fred_running) {
851  }
852 
853  starfield_generate_bitmap_buffers();
854 }
855 
856 
857 extern object * Player_obj;
858 
859 #define STAR_AMOUNT_DEFAULT 0.75f
860 #define STAR_DIM_DEFAULT 7800.0f
861 #define STAR_CAP_DEFAULT 75.0f
862 #define STAR_MAX_LENGTH_DEFAULT 0.04f // 312
863 
868 
869 #define STAR_FLAG_TAIL (1<<0) // Draw a tail when moving
870 #define STAR_FLAG_DIM (1<<1) // Dim as you move
871 #define STAR_FLAG_ANTIALIAS (1<<2) // Draw the star using antialiased lines
872 #define STAR_FLAG_DEFAULT (STAR_FLAG_TAIL | STAR_FLAG_DIM)
873 
875 
876 //XSTR:OFF
877 DCF(stars,"Set parameters for starfield")
878 {
879  SCP_string arg;
880  float val_f;
881  int val_i;
882 
883  if (dc_optional_string_either("help", "--help")) {
884  dc_printf( "Usage: stars keyword\nWhere keyword can be in the following forms:\n" );
885  dc_printf( "stars default Resets stars to all default values\n" );
886  dc_printf( "stars num X Sets number of stars to X. Between 0 and %d.\n", MAX_STARS );
887  dc_printf( "stars tail X Where X is the percent of 'tail' between 0 and 1.0\n" );
888  dc_printf( "stars dim X Where X is the amount stars dim between 0 and 255.0\n" );
889  dc_printf( "stars cap X Where X is the cap of dimming between 0 and 255.\n" );
890  dc_printf( "stars len X Where X is the cap of length.\n" );
891  dc_printf( "stars m0 Macro0. Old 'pixel type' crappy stars. flags=none\n" );
892  dc_printf( "stars m1 Macro1. (default) tail=.75, dim=20.0, cap=75.0, flags=dim,tail\n" );
893  dc_printf( "stars m2 Macro2. tail=.75, dim=20.0, cap=75.0, flags=dim,tail,aa\n" );
894  dc_printf( "stars flag X Toggles flag X, where X is tail or dim or aa (aa=antialias)\n" );
895  dc_printf( "\nHINT: set cap to 0 to get dim rate and tail down, then use\n" );
896  dc_printf( "cap to keep the lines from going away when moving too fast.\n" );
897  dc_printf( "\nUse '? stars' to see current values.\n" );
898  return; // don't print status if help is printed. Too messy.
899  }
900 
901  if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
902  dc_printf( "Num_stars: %d\n", Num_stars );
903  dc_printf( "Tail: %.2f\n", Star_amount );
904  dc_printf( "Dim : %.2f\n", Star_dim );
905  dc_printf( "Cap : %.2f\n", Star_cap );
906  dc_printf( "Max length: %.2f\n", Star_max_length );
907  dc_printf( "Flags:\n" );
908  dc_printf( " Tail : %s\n", (Star_flags&STAR_FLAG_TAIL?"On":"Off") );
909  dc_printf( " Dim : %s\n", (Star_flags&STAR_FLAG_DIM?"On":"Off") );
910  dc_printf( " Antialias: %s\n", (Star_flags&STAR_FLAG_ANTIALIAS?"On":"Off") );
911  dc_printf( "\nTHESE AREN'T SAVED TO DISK, SO IF YOU TWEAK\n" );
912  dc_printf( "THESE AND LIKE THEM, WRITE THEM DOWN!!\n" );
913  return;
914  }
915 
917  // "stars default" is handled by "stars m1"
918  if (arg == "num") {
919  dc_stuff_int(&val_i);
920 
921  CLAMP(val_i, 0, MAX_STARS);
922  Num_stars = val_i;
923 
924  dc_printf("Num_stars set to %i\n", Num_stars);
925 
926  } else if (arg == "tail") {
927  dc_stuff_float(&val_f);
928  CLAMP(val_f, 0.0, 1.0);
929  Star_amount = val_f;
930 
931  dc_printf("Star_amount set to %f\n", Star_amount);
932 
933  } else if (arg == "dim") {
934  dc_stuff_float(&val_f);
935 
936  if (val_f > 0.0f ) {
937  Star_dim = val_f;
938  dc_printf("Star_dim set to %f\n", Star_dim);
939 
940  } else {
941  dc_printf("Error: Star_dim value must be non-negative\n");
942  }
943 
944  } else if (arg == "cap") {
945  dc_stuff_float(&val_f);
946  CLAMP(val_f, 0.0, 255);
947  Star_cap = val_f;
948 
949  dc_printf("Star_cap set to %f\n", Star_cap);
950 
951  } else if (arg == "len") {
952  dc_stuff_float(&Star_max_length);
953 
954  dc_printf("Star_max_length set to %f\n", Star_max_length);
955 
956  } else if (arg == "m0") {
957  Star_amount = 0.0f;
958  Star_dim = 0.0f;
959  Star_cap = 0.0f;
960  Star_flags = 0;
961  Star_max_length = STAR_MAX_LENGTH_DEFAULT;
962 
963  dc_printf("Starfield set: Old 'pixel type' crappy stars. flags=none\n");
964 
965  } else if ((arg == "m1") || (arg == "default")) {
966  Star_amount = STAR_AMOUNT_DEFAULT;
967  Star_dim = STAR_DIM_DEFAULT;
968  Star_cap = STAR_CAP_DEFAULT;
969  Star_flags = STAR_FLAG_DEFAULT;
970  Star_max_length = STAR_MAX_LENGTH_DEFAULT;
971 
972  dc_printf("Starfield set: (default) tail=.75, dim=20.0, cap=75.0, flags=dim,tail\n");
973 
974  } else if (arg == "m2") {
975  Star_amount = 0.75f;
976  Star_dim = 20.0f;
977  Star_cap = 75.0f;
979  Star_max_length = STAR_MAX_LENGTH_DEFAULT;
980 
981  dc_printf("Starfield set: tail=.75, dim=20.0, cap=75.0, flags=dim,tail,aa\n");
982 
983  } else if (arg == "flag") {
985  if (arg == "tail") {
986  Star_flags ^= STAR_FLAG_TAIL;
987  } else if (arg == "dim" ) {
988  Star_flags ^= STAR_FLAG_DIM;
989  } else if (arg == "aa" ) {
990  Star_flags ^= STAR_FLAG_ANTIALIAS;
991  } else {
992  dc_printf("Error: unknown flag argument '%s'\n", arg.c_str());
993  }
994 
995  } else {
996  dc_printf("Error: Unknown argument '%s'", arg.c_str());
997  }
998 }
999 //XSTR:ON
1000 
1001 int reload_old_debris = 1; // If set to one, then reload all the last_pos of the debris
1002 
1003 // Call this if camera "cuts" or moves long distances
1004 // so blur effect doesn't draw lines all over the screen.
1006 {
1007  last_stars_filled = 0;
1008  reload_old_debris = 1;
1009 }
1010 
1011 //#define TIME_STAR_CODE // enable to time star code
1012 
1013 extern int Sun_drew;
1014 
1015 // get the world coords of the sun pos on the unit sphere.
1016 void stars_get_sun_pos(int sun_n, vec3d *pos)
1017 {
1018  vec3d temp;
1019  matrix rot;
1020 
1021  // sanity
1022  Assert( sun_n < (int)Suns.size() );
1023 
1024  if ( (sun_n >= (int)Suns.size()) || (sun_n < 0) ) {
1025  return;
1026  }
1027 
1028  // rotate the sun properly
1029  temp = vmd_zero_vector;
1030  temp.xyz.z = 1.0f;
1031 
1032  // rotation matrix
1033  vm_angles_2_matrix(&rot, &Suns[sun_n].ang);
1034  vm_vec_rotate(pos, &temp, &rot);
1035 }
1036 
1037 // draw sun
1038 void stars_draw_sun(int show_sun)
1039 {
1040  int idx;
1041  vec3d sun_pos;
1042  vec3d sun_dir;
1043  vertex sun_vex;
1044  starfield_bitmap *bm;
1045  float local_scale;
1046 
1047  // should we even be here?
1048  if (!show_sun)
1049  return;
1050 
1051  // no suns drew yet
1052  Sun_drew = 0;
1053 
1054  // draw all suns
1055  int num_suns = (int)Suns.size();
1056 
1057  for (idx = 0; idx < num_suns; idx++) {
1058  // get the instance
1059  if (Suns[idx].star_bitmap_index < 0)
1060  return;
1061 
1062  bm = &Sun_bitmaps[Suns[idx].star_bitmap_index];
1063 
1064  // if no bitmap then bail...
1065  if (bm->bitmap_id < 0)
1066  continue;
1067 
1068  memset( &sun_vex, 0, sizeof(vertex) );
1069 
1070  // get sun pos
1071  sun_pos = vmd_zero_vector;
1072  sun_pos.xyz.y = 1.0f;
1073  stars_get_sun_pos(idx, &sun_pos);
1074 
1075  // get the direction
1076  sun_dir = sun_pos;
1077  vm_vec_normalize(&sun_dir);
1078 
1079  // add the light source corresponding to the sun, except when rendering to an envmap
1080  if ( !Rendering_to_env )
1081  light_add_directional(&sun_dir, bm->i, bm->r, bm->g, bm->b, bm->spec_r, bm->spec_g, bm->spec_b, true);
1082 
1083  // if supernova
1084  if ( supernova_active() && (idx == 0) )
1085  local_scale = 1.0f + (SUPERNOVA_SUN_SCALE * supernova_pct_complete());
1086  else
1087  local_scale = 1.0f;
1088 
1089  // draw the sun itself, keep track of how many we drew
1090  if (bm->fps) {
1091  gr_set_bitmap(bm->bitmap_id + ((timestamp() / (int)(bm->fps)) % bm->n_frames), GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.999f);
1092  } else {
1094  }
1095 
1096  g3_rotate_faraway_vertex(&sun_vex, &sun_pos);
1097 
1098  if ( !g3_draw_bitmap(&sun_vex, 0, 0.05f * Suns[idx].scale_x * local_scale, TMAP_FLAG_TEXTURED) )
1099  Sun_drew++;
1100  }
1101 }
1102 
1103 // draw a star's lens-flare
1104 void stars_draw_lens_flare(vertex *sun_vex, int sun_n)
1105 {
1106  starfield_bitmap *bm;
1107  int i,j;
1108  float dx,dy;
1109  vertex flare_vex = *sun_vex; //copy over to flare_vex to get all sorts of properties
1110 
1111  Assert( sun_n < (int)Suns.size() );
1112 
1113  if ( (sun_n >= (int)Suns.size()) || (sun_n < 0) ) {
1114  return;
1115  }
1116 
1117  // get the instance
1118  if (Suns[sun_n].star_bitmap_index < 0) {
1119  return;
1120  } else {
1121  bm = &Sun_bitmaps[Suns[sun_n].star_bitmap_index];
1122  }
1123 
1124  if (!bm->flare)
1125  return;
1126 
1127  /* (dx,dy) is a 2d vector equal to two times the vector from the sun's
1128  position to the center fo the screen meaning it is the vector to the
1129  opposite position on the screen. */
1130  dx = 2.0f*(i2fl(gr_screen.clip_right-gr_screen.clip_left)*0.5f - sun_vex->screen.xyw.x);
1131  dy = 2.0f*(i2fl(gr_screen.clip_bottom-gr_screen.clip_top)*0.5f - sun_vex->screen.xyw.y);
1132 
1133  for (j = 0; j < bm->n_flare_bitmaps; j++)
1134  {
1135  // if no bitmap then bail...
1136  if (bm->flare_bitmaps[j].bitmap_id < 0)
1137  continue;
1138 
1140 
1141  for (i = 0; i < bm->n_flares; i++) {
1142  // draw sorted by texture, to minimize texture changes. not the most efficient way, but better than non-sorted
1143  if (bm->flare_infos[i].tex_num == j) {
1144 // gr_set_bitmap(bm->flare_bitmaps[bm->flare_infos[i].tex_num], GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.999f);
1145  flare_vex.screen.xyw.x = sun_vex->screen.xyw.x + dx * bm->flare_infos[i].pos;
1146  flare_vex.screen.xyw.y = sun_vex->screen.xyw.y + dy * bm->flare_infos[i].pos;
1147  g3_draw_bitmap(&flare_vex, 0, 0.05f * bm->flare_infos[i].scale, TMAP_FLAG_TEXTURED);
1148  }
1149  }
1150  }
1151 }
1152 
1153 // draw the corresponding glow for sun_n
1154 void stars_draw_sun_glow(int sun_n)
1155 {
1156  starfield_bitmap *bm;
1157  vec3d sun_pos, sun_dir;
1158  vertex sun_vex;
1159  float local_scale;
1160 
1161  // sanity
1162  //WMC - Dunno why this is getting hit...
1163  //Assert( sun_n < (int)Suns.size() );
1164 
1165  if ( (sun_n >= (int)Suns.size()) || (sun_n < 0) ) {
1166  return;
1167  }
1168 
1169  // get the instance
1170  if (Suns[sun_n].star_bitmap_index < 0)
1171  return;
1172 
1173  bm = &Sun_bitmaps[Suns[sun_n].star_bitmap_index];
1174 
1175  // if no bitmap then bail...
1176  if (bm->glow_bitmap < 0)
1177  return;
1178 
1179  memset( &sun_vex, 0, sizeof(vertex) );
1180 
1181  // get sun pos
1182  sun_pos = vmd_zero_vector;
1183  sun_pos.xyz.y = 1.0f;
1184  stars_get_sun_pos(sun_n, &sun_pos);
1185 
1186  // get the direction
1187  sun_dir = sun_pos;
1188  vm_vec_normalize(&sun_dir);
1189 
1190  // if supernova
1191  if ( supernova_active() && (sun_n == 0) )
1192  local_scale = 1.0f + (SUPERNOVA_SUN_SCALE * supernova_pct_complete());
1193  else
1194  local_scale = 1.0f;
1195 
1196  // draw the sun itself, keep track of how many we drew
1197  if (bm->glow_fps) {
1199  } else {
1201  }
1202 
1203  g3_rotate_faraway_vertex(&sun_vex, &sun_pos);
1204  int zbuff = gr_zbuffer_set(GR_ZBUFF_NONE);
1205  g3_draw_bitmap(&sun_vex, 0, 0.10f * Suns[sun_n].scale_x * local_scale, TMAP_FLAG_TEXTURED);
1206 
1207  if (bm->flare) {
1208  vec3d light_dir;
1209  vec3d local_light_dir;
1210  light_get_global_dir(&light_dir, sun_n);
1211  vm_vec_rotate(&local_light_dir, &light_dir, &Eye_matrix);
1212  float dot=vm_vec_dot( &light_dir, &Eye_matrix.vec.fvec );
1213  if (dot > 0.7f) // Only render the flares if the sun is reasonably near the center of the screen
1214  stars_draw_lens_flare(&sun_vex, sun_n);
1215  }
1216 
1217  gr_zbuffer_set(zbuff);
1218 }
1219 
1220 
1221 // draw bitmaps
1222 void stars_draw_bitmaps(int show_bitmaps)
1223 {
1224  int idx;
1225  int star_index;
1226 
1227  // should we even be here?
1228  if ( !show_bitmaps )
1229  return;
1230 
1231  // if we're in the nebula, don't render any backgrounds
1233  return;
1234 
1235  // detail settings
1236  if ( !Detail.planets_suns )
1237  return;
1238 
1239  if ( !Cmdline_nohtl ) {
1241  }
1242 
1243  // turn off culling
1244  int cull = gr_set_cull(0);
1245 
1246  // turn off zbuffering
1247  int saved_zbuffer_mode = gr_zbuffer_get();
1249 
1250  int sb_instances = (int)Starfield_bitmap_instances.size();
1251 
1252  for (idx = 0; idx < sb_instances; idx++) {
1253  // lookup the info index
1254  star_index = Starfield_bitmap_instances[idx].star_bitmap_index;
1255 
1256  if (star_index < 0) {
1257  continue;
1258  }
1259 
1260  // if no bitmap then bail...
1261  if (Starfield_bitmaps[star_index].bitmap_id < 0) {
1262  continue;
1263  }
1264 
1266 
1267  if (Starfield_bitmaps[star_index].xparent) {
1268  if (Starfield_bitmaps[star_index].fps) {
1269  gr_set_bitmap(Starfield_bitmaps[star_index].bitmap_id + ((timestamp() / (int)(Starfield_bitmaps[star_index].fps)) % Starfield_bitmaps[star_index].n_frames));
1270  } else {
1271  gr_set_bitmap(Starfield_bitmaps[star_index].bitmap_id);
1272  }
1273 
1274  tmap_flags |= TMAP_FLAG_XPARENT;
1275  } else {
1276  if (Starfield_bitmaps[star_index].fps) {
1277  gr_set_bitmap(Starfield_bitmaps[star_index].bitmap_id + ((timestamp() / (int)(Starfield_bitmaps[star_index].fps)) % Starfield_bitmaps[star_index].n_frames), GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.9999f);
1278  } else {
1279  gr_set_bitmap(Starfield_bitmaps[star_index].bitmap_id, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.9999f);
1280  }
1281  }
1282 
1283  gr_render(Starfield_bitmap_instances[idx].n_verts, Starfield_bitmap_instances[idx].verts, tmap_flags);
1284  }
1285 
1286  // turn on culling
1287  gr_set_cull(cull);
1288 
1289  // restore zbuffer
1290  gr_zbuffer_set(saved_zbuffer_mode);
1291 
1292  if ( !Cmdline_nohtl )
1294 }
1295 
1296 extern int Interp_subspace;
1297 extern float Interp_subspace_offset_u;
1299 extern float Interp_subspace_offset_v;
1300 
1301 float subspace_offset_u = 0.0f;
1303 float subspace_offset_v = 0.0f;
1304 
1305 float subspace_u_speed = 0.07f; // how fast u changes
1306 float subspace_v_speed = 0.05f; // how fast v changes
1307 
1309 
1310 float Subspace_glow_frame = 0.0f;
1311 float Subspace_glow_rate = 1.0f;
1312 
1313 
1314 //XSTR:OFF
1315 DCF(subspace_set,"Set parameters for subspace effect")
1316 {
1317  SCP_string arg;
1318  float value;
1319 
1320  if (dc_optional_string_either("help", "--help")) {
1321  dc_printf( "Usage: subspace [--status] <axis> <speed>\n");
1322  dc_printf("[--status] -- Displays the current speeds for both axes\n");
1323  dc_printf("<axis> -- May be either 'u' or 'v', and corresponds to the texture axis\n");
1324  dc_printf("<speed> -- is the speed along the axis that the texture is moved\n");
1325  return;
1326  }
1327 
1328  if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
1329  dc_printf( "u: %.2f\n", subspace_u_speed );
1330  dc_printf( "v: %.2f\n", subspace_v_speed );
1331  return;
1332  }
1333 
1334  dc_stuff_string_white(arg);
1335  if (arg == "u") {
1336  dc_stuff_float(&value);
1337 
1338  if ( value < 0.0f ) {
1339  dc_printf("Error: speed must be non-negative");
1340  return;
1341  }
1342  subspace_u_speed = value;
1343 
1344  } else if (arg == "v") {
1345  dc_stuff_float(&value);
1346 
1347  if (value < 0.0f) {
1348  dc_printf("Error: speed must be non-negative");
1349  return;
1350  }
1351  subspace_v_speed = value;
1352 
1353  } else {
1354  dc_printf("Error: Unknown axis '%s'", arg.c_str());
1355  }
1356 }
1357 //XSTR:ON
1358 
1360 {
1361  int framenum = 0;
1362 
1363  if ( Subspace_model_inner == -1 ) {
1364  Subspace_model_inner = model_load( "subspace_small.pof", 0, NULL );
1365  Assert(Subspace_model_inner >= 0);
1366  }
1367 
1368  if ( Subspace_model_outer == -1 ) {
1369  Subspace_model_outer = model_load( "subspace_big.pof", 0, NULL );
1370  Assert(Subspace_model_outer >= 0);
1371  }
1372 
1373  if ( Subspace_glow_bitmap == -1 ) {
1374  Subspace_glow_bitmap = bm_load( NOX("SunGlow01"));
1375  Assert(Subspace_glow_bitmap >= 0);
1376  }
1377 
1378  if ( !Rendering_to_env ) {
1379  Subspace_glow_frame += flFrametime * 1.0f;
1380 
1381  float total_time = i2fl(NOISE_NUM_FRAMES) / 15.0f;
1382 
1383  // Sanity checks
1384  if ( Subspace_glow_frame < 0.0f )
1385  Subspace_glow_frame = 0.0f;
1386  if ( Subspace_glow_frame > 100.0f )
1387  Subspace_glow_frame = 0.0f;
1388 
1389  while ( Subspace_glow_frame > total_time ) {
1390  Subspace_glow_frame -= total_time;
1391  }
1392 
1393  framenum = fl2i( (Subspace_glow_frame*NOISE_NUM_FRAMES) / total_time );
1394 
1395  if ( framenum < 0 )
1396  framenum = 0;
1397  if ( framenum >= NOISE_NUM_FRAMES )
1398  framenum = NOISE_NUM_FRAMES-1;
1399 
1400  subspace_offset_u += flFrametime*subspace_u_speed;
1401  if (subspace_offset_u > 1.0f ) {
1402  subspace_offset_u -= 1.0f;
1403  }
1404 
1405  subspace_offset_u_inner += flFrametime*subspace_u_speed*3.0f;
1406  if (subspace_offset_u > 1.0f ) {
1407  subspace_offset_u -= 1.0f;
1408  }
1409 
1410  subspace_offset_v += flFrametime*subspace_v_speed;
1411  if (subspace_offset_v > 1.0f ) {
1412  subspace_offset_v -= 1.0f;
1413  }
1414  }
1415 
1416 
1417  matrix tmp;
1418  angles angs = { 0.0f, 0.0f, 0.0f };
1419 
1420  angs.b = subspace_offset_v * PI2;
1421 
1422  vm_angles_2_matrix(&tmp,&angs);
1423 
1424  int saved_gr_zbuffering = gr_zbuffer_get();
1425 
1427 
1428  int render_flags = MR_NO_LIGHTING | MR_ALL_XPARENT;
1429 
1430  Interp_subspace = 1;
1431  Interp_subspace_offset_u = 1.0f - subspace_offset_u;
1432  Interp_subspace_offset_v = 0.0f;
1433 
1434  model_render_params render_info;
1435  render_info.set_alpha(1.0f);
1436  render_info.set_flags(render_flags);
1437 
1438  if (!Cmdline_nohtl)
1439  gr_set_texture_panning(Interp_subspace_offset_v, Interp_subspace_offset_u, true);
1440 
1441  model_render_immediate( &render_info, Subspace_model_outer, &tmp, &Eye_position); //MR_NO_CORRECT|MR_SHOW_OUTLINE
1442 
1443  if (!Cmdline_nohtl)
1444  gr_set_texture_panning(0, 0, false);
1445 
1446  Interp_subspace = 1;
1447  Interp_subspace_offset_u = 1.0f - subspace_offset_u_inner;
1448  Interp_subspace_offset_v = 0.0f;
1449 
1450  angs.b = -subspace_offset_v * PI2;
1451 
1452  vm_angles_2_matrix(&tmp,&angs);
1453 
1454  render_info.set_color(255, 255, 255);
1455  render_info.set_alpha(1.0f);
1456  render_info.set_flags(render_flags);
1457 
1458  if (!Cmdline_nohtl)
1459  gr_set_texture_panning(Interp_subspace_offset_v, Interp_subspace_offset_u, true);
1460 
1461  model_render_immediate( &render_info, Subspace_model_inner, &tmp, &Eye_position ); //MR_NO_CORRECT|MR_SHOW_OUTLINE
1462 
1463  if (!Cmdline_nohtl)
1464  gr_set_texture_panning(0, 0, false);
1465 
1466  //Render subspace glows here and not as thrusters - Valathil
1467  vec3d glow_pos;
1468  vertex glow_vex;
1469 
1470  glow_pos.xyz.x = 0.0f;
1471  glow_pos.xyz.y = 0.0f;
1472  glow_pos.xyz.z = 100.0f;
1473 
1474  gr_set_bitmap(Subspace_glow_bitmap, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.0f);
1475  g3_rotate_faraway_vertex(&glow_vex, &glow_pos);
1476  g3_draw_bitmap(&glow_vex, 0, 17.0f + 0.5f * Noise[framenum], TMAP_FLAG_TEXTURED);
1477 
1478  glow_pos.xyz.z = -100.0f;
1479 
1480  g3_rotate_faraway_vertex(&glow_vex, &glow_pos);
1481  g3_draw_bitmap(&glow_vex, 0, 17.0f + 0.5f * Noise[framenum], TMAP_FLAG_TEXTURED);
1482 
1483  Interp_subspace = 0;
1484  gr_zbuffer_set(saved_gr_zbuffering);
1485 }
1486 
1487 
1488 #ifdef NEW_STARS
1489 //each star is actualy a line
1490 //so each star point is actualy two points
1491 struct star_point {
1492  star_point() {
1493  memset(p1.color,INT_MAX,4);
1494  p2.color[0]=64;
1495  p2.color[1]=64;
1496  p2.color[2]=64;
1497  p2.color[3]=64;
1498  }
1499  colored_vector p1,p2;
1500  void set(vertex* P1,vertex* P2, color*Col) {
1501  p1.vec.set_screen_vert(*P1);
1502  p2.vec.set_screen_vert(*P2);
1503  if(gr_screen.mode == GR_OPENGL)
1504  memcpy(p1.color, &Col->red,3);
1505  else {
1506  memcpy(&p1.color[1], &Col->red,3);
1507  }
1508  };
1509 };
1510 
1511 class star_point_list {
1512  int n_points;
1513  star_point *point_list;
1514 public:
1515  star_point_list():n_points(0),point_list(NULL){};
1516  ~star_point_list(){if(point_list)delete[]point_list;};
1517 
1518  void allocate(int size){
1519  if(size<=n_points)return;
1520  if(point_list)delete[]point_list;
1521  point_list = new star_point[size];
1522  n_points = size;
1523  }
1524  star_point* operator[] (int idx) {
1525  return &point_list[idx];
1526  }
1527  colored_vector* get_buffer(){return &point_list->p1;};
1528 };
1529 
1530 star_point_list star_list;
1531 
1532 void new_stars_draw_stars()//don't use me yet, I'm still haveing my API interface figured out-Bobboau
1533 {
1534  star_list.allocate(Num_stars);
1535 
1536  //Num_stars = 1;
1537  int i;
1538  star *sp;
1539  float dist = 0.0f;
1540  float ratio;
1541  int color;
1542  float colorf;
1543  vertex p1, p2;
1544  int can_draw = 1;
1545 
1546  if ( !last_stars_filled ) {
1547  for (sp=Stars,i=0; i<Num_stars; i++, sp++ ) {
1548  vertex p2;
1549  g3_rotate_faraway_vertex(&p2, &sp->pos);
1550  sp->last_star_pos.xyz.x = p2.x;
1551  sp->last_star_pos.xyz.y = p2.y;
1552  sp->last_star_pos.xyz.z = p2.z;
1553  }
1554  }
1555 
1556  int tmp_num_stars;
1557 
1558  tmp_num_stars = (Detail.num_stars*Num_stars)/MAX_DETAIL_LEVEL;
1559  if (tmp_num_stars < 0 ) {
1560  tmp_num_stars = 0;
1561  } else if ( tmp_num_stars > Num_stars ) {
1562  tmp_num_stars = Num_stars;
1563  }
1564 
1565  int stars_to_draw = 0;
1566  for (sp=Stars,i=0; i<tmp_num_stars; i++, sp++ ) {
1567  can_draw=1;
1568  memset(&p1, 0, sizeof(vertex));
1569  memset(&p2, 0, sizeof(vertex));
1570 
1571  // This makes a star look "proper" by not translating the
1572  // point around the viewer's eye before rotation. In other
1573  // words, when the ship translates, the stars do not change.
1574 
1575  g3_rotate_faraway_vertex(&p2, &sp->pos);
1576  if ( p2.codes ) {
1577  can_draw = 0;
1578  } else {
1579  g3_project_vertex(&p2);
1580  if ( p2.flags & PF_OVERFLOW ) {
1581  can_draw = 0;
1582  }
1583  }
1584 
1585 
1586 
1587  if ( can_draw && (Star_flags & (STAR_FLAG_TAIL|STAR_FLAG_DIM)) ) {
1588 
1589  dist = vm_vec_dist_quick( &sp->last_star_pos, (vec3d *)&p2.x );
1590 
1591  if ( dist > Star_max_length ) {
1592  ratio = Star_max_length / dist;
1593  dist = Star_max_length;
1594  } else {
1595  ratio = 1.0f;
1596  }
1597 
1598  ratio *= Star_amount;
1599 
1600  p1.x = p2.x + (sp->last_star_pos.xyz.x-p2.x)*ratio;
1601  p1.y = p2.y + (sp->last_star_pos.xyz.y-p2.y)*ratio;
1602  p1.z = p2.z + (sp->last_star_pos.xyz.z-p2.z)*ratio;
1603 
1604  p1.flags = 0; // not projected
1605  g3_code_vertex( &p1 );
1606 
1607  if ( p1.codes ) {
1608  can_draw = 0;
1609  } else {
1610  g3_project_vertex(&p1);
1611  if ( p1.flags & PF_OVERFLOW ) {
1612  can_draw = 0;
1613  }
1614  }
1615  }
1616 
1617  sp->last_star_pos.xyz.x = p2.x;
1618  sp->last_star_pos.xyz.y = p2.y;
1619  sp->last_star_pos.xyz.z = p2.z;
1620 
1621  if ( !can_draw ) continue;
1622 
1623  if ( Star_flags & STAR_FLAG_DIM ) {
1624  colorf = 255.0f - dist*Star_dim;
1625  if ( colorf < Star_cap )
1626  colorf = Star_cap;
1627  color = (fl2i(colorf)*(i&7))/256;
1628  } else {
1629  color = i & 7;
1630  }
1631 
1632  p1.sx-=1.5f;
1633  p1.sy-=1.5f;
1634  p2.sx+=1.5f;
1635  p2.sy+=1.5f;
1636  star_list[stars_to_draw++]->set(&p2,&p1,&sp->col);
1637  }
1638  gr_set_color_fast( &Stars->col );
1640  gr_draw_line_list(star_list.get_buffer(), stars_to_draw);
1641 
1642 }
1643 #endif // NEW_STARS
1644 
1645 
1647 {
1648  int i;
1649  star *sp;
1650  float dist = 0.0f;
1651  float ratio;
1652  vDist vDst;
1653  vertex p1, p2;
1654  int can_draw = 1;
1655 
1656  if ( !last_stars_filled ) {
1657  for (i = 0; i < Num_stars; i++) {
1658  g3_rotate_faraway_vertex(&p2, &Stars[i].pos);
1659  Stars[i].last_star_pos = p2.world;
1660  }
1661  }
1662 
1663  int tmp_num_stars = 0;
1664 
1665  tmp_num_stars = (Detail.num_stars * Num_stars) / MAX_DETAIL_LEVEL;
1666  CLAMP(tmp_num_stars, 0, Num_stars);
1667 
1668 
1669  for (i = 0; i < tmp_num_stars; i++) {
1670  sp = &Stars[i];
1671 
1672  can_draw = 1;
1673  memset(&p1, 0, sizeof(vertex));
1674  memset(&p2, 0, sizeof(vertex));
1675 
1676  // This makes a star look "proper" by not translating the
1677  // point around the viewer's eye before rotation. In other
1678  // words, when the ship translates, the stars do not change.
1679 
1680  g3_rotate_faraway_vertex(&p2, &sp->pos);
1681  if ( p2.codes ) {
1682  can_draw = 0;
1683  } else {
1684  g3_project_vertex(&p2);
1685  if ( p2.flags & PF_OVERFLOW ) {
1686  can_draw = 0;
1687  }
1688  }
1689 
1690  if ( can_draw && (Star_flags & (STAR_FLAG_TAIL|STAR_FLAG_DIM)) ) {
1691  dist = vm_vec_dist_quick( &sp->last_star_pos, &p2.world );
1692 
1693  if ( dist > Star_max_length ) {
1694  ratio = Star_max_length / dist;
1695  dist = Star_max_length;
1696  } else {
1697  ratio = 1.0f;
1698  }
1699 
1700  ratio *= Star_amount;
1701 
1702  vm_vec_sub(&p1.world, &sp->last_star_pos, &p2.world);
1703  vm_vec_scale(&p1.world, ratio);
1704  vm_vec_add2(&p1.world, &p2.world);
1705 
1706  p1.flags = 0; // not projected
1707  g3_code_vertex( &p1 );
1708 
1709  if ( p1.codes ) {
1710  can_draw = 0;
1711  } else {
1712  g3_project_vertex(&p1);
1713  if ( p1.flags & PF_OVERFLOW ) {
1714  can_draw = 0;
1715  }
1716  }
1717  }
1718 
1719  sp->last_star_pos = p2.world;
1720 
1721  if ( !can_draw )
1722  continue;
1723 
1724  gr_set_color_fast( &sp->col );
1725 
1726  vDst.x = fl2i(p1.screen.xyw.x) - fl2i(p2.screen.xyw.x);
1727  vDst.y = fl2i(p1.screen.xyw.y) - fl2i(p2.screen.xyw.y);
1728 
1729  if ( ((vDst.x * vDst.x) + (vDst.y * vDst.y)) <= 4 ) {
1730  p1.screen.xyw.x = p2.screen.xyw.x + 1.0f;
1731  p1.screen.xyw.y = p2.screen.xyw.y;
1732  }
1733 
1734  gr_aaline(&p1, &p2);
1735  }
1736 }
1737 
1739 {
1740  int i;
1741  float vdist;
1742  vec3d tmp;
1743  vertex p;
1744 
1745  extern bool Motion_debris_override;
1746 
1747  if (Motion_debris_override)
1748  return;
1749 
1750  gr_set_color( 0, 0, 0 );
1751 
1752  // turn off fogging
1754  gr_fog_set(GR_FOGMODE_NONE, 0, 0, 0);
1755  }
1756 
1757  old_debris * d = odebris;
1758 
1759  for (i=0; i<MAX_DEBRIS; i++, d++ ) {
1760  if (!d->active) {
1761  d->pos.xyz.x = f2fl(myrand() - RAND_MAX_2);
1762  d->pos.xyz.y = f2fl(myrand() - RAND_MAX_2);
1763  d->pos.xyz.z = f2fl(myrand() - RAND_MAX_2);
1764 
1765  vm_vec_normalize(&d->pos);
1766 
1767  vm_vec_scale(&d->pos, MAX_DIST);
1768  vm_vec_add2(&d->pos, &Eye_position );
1769  d->active = 1;
1770  d->vclip = i % MAX_DEBRIS_VCLIPS; //rand()
1771 
1772  // if we're in full neb mode
1774  d->size = i2fl(myrand() % 4)*BASE_SIZE_NEB;
1775  } else {
1776  d->size = i2fl(myrand() % 4)*BASE_SIZE;
1777  }
1778 
1779  vm_vec_sub( &d->last_pos, &d->pos, &Eye_position );
1780  }
1781 
1782  if ( reload_old_debris ) {
1783  vm_vec_sub( &d->last_pos, &d->pos, &Eye_position );
1784  }
1785 
1786  g3_rotate_vertex(&p, &d->pos);
1787 
1788  if (p.codes == 0) {
1790  frame %= Debris_vclips[d->vclip].nframes;
1791 
1793  gr_set_bitmap( Debris_vclips[d->vclip].bm + frame, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.3f);
1794  } else {
1795  gr_set_bitmap( Debris_vclips[d->vclip].bm + frame, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.0f);
1796  }
1797 
1798  vm_vec_add( &tmp, &d->last_pos, &Eye_position );
1799  g3_draw_laser( &d->pos,d->size,&tmp,d->size, TMAP_FLAG_TEXTURED|TMAP_FLAG_XPARENT, 25.0f );
1800  }
1801 
1802  vm_vec_sub( &d->last_pos, &d->pos, &Eye_position );
1803 
1804  vdist = vm_vec_mag_quick(&d->last_pos);
1805 
1806  if ( (vdist < MIN_DIST_RANGE) || (vdist > MAX_DIST_RANGE) )
1807  d->active = 0;
1808  }
1809 
1810  reload_old_debris = 0;
1811 }
1812 
1813 void stars_draw(int show_stars, int show_suns, int show_nebulas, int show_subspace, int env)
1814 {
1815  int gr_zbuffering_save = gr_zbuffer_get();
1817 
1818  Rendering_to_env = env;
1819 
1820  if (show_subspace)
1821  subspace_render();
1822 
1823  if (Num_stars >= MAX_STARS)
1824  Num_stars = MAX_STARS;
1825 
1826 #ifdef TIME_STAR_CODE
1827  fix xt1, xt2;
1828  xt1 = timer_get_fixed_seconds();
1829 #endif
1830 
1832  nebula_render();
1833  }
1834 
1835  // draw background stuff
1836  if ( (Neb2_render_mode != NEB2_RENDER_POLY) && (Neb2_render_mode != NEB2_RENDER_LAME) && show_stars ) {
1837  // semi-hack, do we don't fog the background
1838  int neb_save = Neb2_render_mode;
1841  Neb2_render_mode = neb_save;
1842  }
1843  else if ( !show_subspace ) // don't render the background pof when rendering subspace
1844  {
1846  }
1847 
1848  if ( !env && show_stars && (Nmodel_num < 0) && (Game_detail_flags & DETAIL_FLAG_STARS) && !(The_mission.flags & MISSION_FLAG_FULLNEB) && (supernova_active() < 3) ) {
1849  stars_draw_stars();
1850  }
1851 
1852  last_stars_filled = 1;
1853 
1854 #ifdef TIME_STAR_CODE
1855  xt2 = timer_get_fixed_seconds();
1856  mprintf(( "Stars: %d\n", xt2-xt1 ));
1857 #endif
1858 
1859  if ( !Rendering_to_env && (Game_detail_flags & DETAIL_FLAG_MOTION) && (!Fred_running) && (supernova_active() < 3) && (!Cmdline_nomotiondebris) ) {
1861  }
1862 
1863  //if we're not drawing them, quit here
1864  if (show_suns) {
1865  stars_draw_sun( show_suns );
1866  stars_draw_bitmaps( show_suns );
1867  }
1868 
1869  gr_zbuffer_set( gr_zbuffering_save );
1870  Rendering_to_env = 0;
1871 }
1872 
1873 void stars_preload_sun_bitmap(char *fname)
1874 {
1875  int idx;
1876 
1877  if (fname == NULL)
1878  return;
1879 
1880  idx = stars_find_sun(fname);
1881 
1882  if (idx == -1) {
1883  return;
1884  }
1885 
1886  Sun_bitmaps[idx].preload = 1;
1887 }
1888 
1890 {
1891  int idx;
1892 
1893  if (fname == NULL)
1894  return;
1895 
1896  idx = stars_find_bitmap(fname);
1897 
1898  if (idx == -1) {
1899  return;
1900  }
1901 
1902  Starfield_bitmaps[idx].preload = 1;
1903 }
1904 
1906 {
1907  int idx, i;
1909  starfield_bitmap *sb;
1910 
1911  // Initialize the subspace stuff
1912 
1913  if ( Game_subspace_effect ) {
1914  Subspace_model_inner = model_load( "subspace_small.pof", 0, NULL );
1915  Assert(Subspace_model_inner >= 0);
1916  Subspace_model_outer = model_load( "subspace_big.pof", 0, NULL );
1917  Assert(Subspace_model_outer >= 0);
1918 
1919  polymodel *pm;
1920 
1921  pm = model_get(Subspace_model_inner);
1922 
1923  nprintf(( "Paging", "Paging in textures for subspace effect.\n" ));
1924 
1925  for (idx = 0; idx < pm->n_textures; idx++) {
1926  pm->maps[idx].PageIn();
1927  }
1928 
1929  pm = model_get(Subspace_model_outer);
1930 
1931  nprintf(( "Paging", "Paging in textures for subspace effect.\n" ));
1932 
1933  for (idx = 0; idx < pm->n_textures; idx++) {
1934  pm->maps[idx].PageIn();
1935  }
1936 
1937  if (Subspace_glow_bitmap < 0) {
1938  Subspace_glow_bitmap = bm_load( NOX("SunGlow01"));
1939  }
1940 
1941  bm_page_in_xparent_texture(Subspace_glow_bitmap);
1942  } else {
1943  Subspace_model_inner = -1;
1944  Subspace_model_outer = -1;
1945 
1946  if (Subspace_glow_bitmap > 0) {
1947  bm_release(Subspace_glow_bitmap);
1948  Subspace_glow_bitmap = -1;
1949  }
1950  }
1951 
1952  // extra SEXP related checks to preload anything that might get used from there
1953  for (idx = 0; idx < (int)Starfield_bitmaps.size(); idx++) {
1954  sb = &Starfield_bitmaps[idx];
1955 
1956  if (sb->used_this_level)
1957  continue;
1958 
1959  if (sb->preload) {
1960  if (sb->bitmap_id < 0) {
1961  sb->bitmap_id = bm_load(sb->filename);
1962 
1963  // maybe didn't load a static image so try for an animated one
1964  if (sb->bitmap_id < 0) {
1965  sb->bitmap_id = bm_load_animation(sb->filename, &sb->n_frames, &sb->fps, NULL, 1);
1966 
1967  if (sb->bitmap_id < 0) {
1968  Warning(LOCATION, "Unable to load starfield bitmap: '%s'!\n", sb->filename);
1969  }
1970  }
1971  }
1972 
1973  // this happens whether it loaded properly or not, no harm should come from it
1974  if (sb->xparent) {
1976  } else {
1978  }
1979 
1980  sb->used_this_level++;
1981  }
1982  }
1983 
1984  for (idx = 0; idx < (int)Sun_bitmaps.size(); idx++) {
1985  sb = &Sun_bitmaps[idx];
1986 
1987  if (sb->used_this_level)
1988  continue;
1989 
1990  if (sb->preload) {
1991  // normal bitmap
1992  if (sb->bitmap_id < 0) {
1993  sb->bitmap_id = bm_load(sb->filename);
1994 
1995  // maybe didn't load a static image so try for an animated one
1996  if (sb->bitmap_id < 0) {
1997  sb->bitmap_id = bm_load_animation(sb->filename, &sb->n_frames, &sb->fps, NULL, 1);
1998 
1999  if (sb->bitmap_id < 0) {
2000  Warning(LOCATION, "Unable to load sun bitmap: '%s'!\n", sb->filename);
2001  }
2002  }
2003  }
2004 
2005  // glow bitmap
2006  if (sb->glow_bitmap < 0) {
2007  sb->glow_bitmap = bm_load(sb->glow_filename);
2008 
2009  // maybe didn't load a static image so try for an animated one
2010  if (sb->glow_bitmap < 0) {
2011  sb->glow_bitmap = bm_load_animation(sb->glow_filename, &sb->glow_n_frames, &sb->glow_fps, NULL, 1);
2012 
2013  if (sb->glow_bitmap < 0) {
2014  Warning(LOCATION, "Unable to load sun glow bitmap: '%s'!\n", sb->glow_filename);
2015  }
2016  }
2017  }
2018 
2019  if (sb->flare) {
2020  for (i = 0; i < MAX_FLARE_BMP; i++) {
2021  if ( !strlen(sb->flare_bitmaps[i].filename) )
2022  continue;
2023 
2024  if (sb->flare_bitmaps[i].bitmap_id < 0) {
2026 
2027  if (sb->flare_bitmaps[i].bitmap_id < 0) {
2028  Warning(LOCATION, "Unable to load sun flare bitmap: '%s'!\n", sb->flare_bitmaps[i].filename);
2029  continue;
2030  }
2031  }
2032 
2034  }
2035  }
2036 
2039 
2040  sb->used_this_level++;
2041  }
2042  }
2043 
2044  // load and page in needed starfield bitmaps
2045  for (idx = 0; idx < (int)Starfield_bitmap_instances.size(); idx++) {
2046  sbi = &Starfield_bitmap_instances[idx];
2047 
2048  if (sbi->star_bitmap_index < 0)
2049  continue;
2050 
2051  sb = &Starfield_bitmaps[sbi->star_bitmap_index];
2052 
2053  if (sb->used_this_level)
2054  continue;
2055 
2056  if (sb->bitmap_id < 0 ) {
2057  sb->bitmap_id = bm_load(sb->filename);
2058 
2059  // maybe didn't load a static image so try for an animated one
2060  if (sb->bitmap_id < 0) {
2061  sb->bitmap_id = bm_load_animation(sb->filename, &sb->n_frames, &sb->fps, NULL, 1);
2062 
2063  if (sb->bitmap_id < 0) {
2064  Warning(LOCATION, "Unable to load starfield bitmap: '%s'!\n", sb->filename);
2065  }
2066  }
2067  }
2068 
2069  // this happens whether it loaded properly or not, no harm should come from it
2070  if (sb->xparent) {
2072  } else {
2074  }
2075 
2076  sb->used_this_level++;
2077  }
2078 
2079  // now for sun bitmaps and glows
2080  for (idx = 0; idx < (int)Suns.size(); idx++) {
2081  sbi = &Suns[idx];
2082 
2083  if (sbi->star_bitmap_index < 0)
2084  continue;
2085 
2086  sb = &Sun_bitmaps[sbi->star_bitmap_index];
2087 
2088  if (sb->used_this_level)
2089  continue;
2090 
2091  // normal bitmap
2092  if (sb->bitmap_id < 0) {
2093  sb->bitmap_id = bm_load(sb->filename);
2094 
2095  // maybe didn't load a static image so try for an animated one
2096  if (sb->bitmap_id < 0) {
2097  sb->bitmap_id = bm_load_animation(sb->filename, &sb->n_frames, &sb->fps, NULL, 1);
2098 
2099  if (sb->bitmap_id < 0) {
2100  Warning(LOCATION, "Unable to load sun bitmap: '%s'!\n", sb->filename);
2101  }
2102  }
2103  }
2104 
2105  // glow bitmap
2106  if (sb->glow_bitmap < 0) {
2107  sb->glow_bitmap = bm_load(sb->glow_filename);
2108 
2109  // maybe didn't load a static image so try for an animated one
2110  if (sb->glow_bitmap < 0) {
2111  sb->glow_bitmap = bm_load_animation(sb->glow_filename, &sb->glow_n_frames, &sb->glow_fps, NULL, 1);
2112 
2113  if (sb->glow_bitmap < 0) {
2114  Warning(LOCATION, "Unable to load sun glow bitmap: '%s'!\n", sb->glow_filename);
2115  }
2116  }
2117  }
2118 
2119  if (sb->flare) {
2120  for (i = 0; i < MAX_FLARE_BMP; i++) {
2121  if ( !strlen(sb->flare_bitmaps[i].filename) )
2122  continue;
2123 
2124  if (sb->flare_bitmaps[i].bitmap_id < 0) {
2126 
2127  if (sb->flare_bitmaps[i].bitmap_id < 0) {
2128  Warning(LOCATION, "Unable to load sun flare bitmap: '%s'!\n", sb->flare_bitmaps[i].filename);
2129  continue;
2130  }
2131  }
2132 
2134  }
2135  }
2136 
2139 
2140  sb->used_this_level++;
2141  }
2142 
2143 
2145  return;
2146 
2147  for (idx = 0; idx < MAX_DEBRIS_VCLIPS; idx++) {
2148  bm_page_in_xparent_texture(Debris_vclips[idx].bm, Debris_vclips[idx].nframes);
2149  }
2150 }
2151 
2152 // background nebula models and planets
2154 {
2155  if (Nmodel_num < 0)
2156  return;
2157 
2158  model_render_params render_info;
2159 
2160  if (Nmodel_bitmap >= 0) {
2161  render_info.set_forced_bitmap(Nmodel_bitmap);
2162  }
2163 
2164  // draw the model at the player's eye with no z-buffering
2165  render_info.set_alpha(1.0f);
2166  render_info.set_flags(Nmodel_flags | MR_SKYBOX);
2167 
2168  model_render_immediate(&render_info, Nmodel_num, &Nmodel_orient, &Eye_position, MODEL_RENDER_ALL, false);
2169 }
2170 
2171 // call this to set a specific model as the background model
2172 void stars_set_background_model(char *model_name, char *texture_name, int flags)
2173 {
2174  if (Nmodel_bitmap >= 0) {
2176  Nmodel_bitmap = -1;
2177  }
2178 
2179  if (Nmodel_num >= 0) {
2181  Nmodel_num = -1;
2182  }
2183 
2184  if (Nmodel_instance_num >= 0) {
2186  Nmodel_instance_num = -1;
2187  }
2188 
2189  Nmodel_flags = flags;
2190 
2191  if ( (model_name == NULL) || (*model_name == '\0') )
2192  return;
2193 
2194  Nmodel_num = model_load(model_name, 0, NULL, -1);
2195  Nmodel_bitmap = bm_load(texture_name);
2196 
2197  if (Nmodel_num >= 0) {
2199 
2202  }
2203  }
2204 }
2205 
2206 // call this to set a specific orientation for the background
2208 {
2209  if (orient == NULL) {
2210  vm_set_identity(&Nmodel_orient);
2211  } else {
2212  Nmodel_orient = *orient;
2213  }
2214 }
2215 
2216 // lookup a starfield bitmap, return index or -1 on fail
2218 {
2219  int idx;
2220 
2221  if (name == NULL)
2222  return -1;
2223 
2224  // lookup
2225  for (idx = 0; idx < (int)Starfield_bitmaps.size(); idx++) {
2226  if ( !stricmp(name, Starfield_bitmaps[idx].filename) ) {
2227  return idx;
2228  }
2229  }
2230 
2231  // not found
2232  return -1;
2233 }
2234 
2235 // lookup a sun by bitmap filename, return index or -1 on fail
2237 {
2238  int idx;
2239 
2240  if (name == NULL)
2241  return -1;
2242 
2243  // lookup
2244  for (idx = 0; idx < (int)Sun_bitmaps.size(); idx++) {
2245  if ( !stricmp(name, Sun_bitmaps[idx].filename) ) {
2246  return idx;
2247  }
2248  }
2249 
2250  // not found
2251  return -1;
2252 }
2253 
2254 // add an instance for a sun (something actually used in a mission)
2255 // NOTE that we assume a duplicate is ok here
2257 {
2258  int idx, i;
2260 
2261  Assert(sun_ptr != NULL);
2262 
2263  // copy information
2264  sbi.ang.p = sun_ptr->ang.p;
2265  sbi.ang.b = sun_ptr->ang.b;
2266  sbi.ang.h = sun_ptr->ang.h;
2267  sbi.scale_x = sun_ptr->scale_x;
2268  sbi.scale_y = sun_ptr->scale_y;
2269  sbi.div_x = sun_ptr->div_x;
2270  sbi.div_y = sun_ptr->div_y;
2271 
2272  idx = stars_find_sun(sun_ptr->filename);
2273 
2274  if (idx == -1) {
2275  Warning(LOCATION, "Trying to add a sun '%s' that does not exist in stars.tbl!", sun_ptr->filename);
2276  return -1;
2277  }
2278 
2279  sbi.star_bitmap_index = idx;
2280 
2281  // make sure any needed bitmaps are loaded
2282  if (Sun_bitmaps[idx].bitmap_id < 0) {
2283  // normal bitmap
2284  Sun_bitmaps[idx].bitmap_id = bm_load(Sun_bitmaps[idx].filename);
2285 
2286  // maybe didn't load a static image so try for an animated one
2287  if (Sun_bitmaps[idx].bitmap_id < 0) {
2288  Sun_bitmaps[idx].bitmap_id = bm_load_animation(Sun_bitmaps[idx].filename, &Sun_bitmaps[idx].n_frames, &Sun_bitmaps[idx].fps, NULL, 1);
2289 
2290  if (Sun_bitmaps[idx].bitmap_id < 0) {
2291  // failed
2292  return -1;
2293  }
2294  }
2295 
2296  // glow bitmap
2297  if (Sun_bitmaps[idx].glow_bitmap < 0) {
2298  Sun_bitmaps[idx].glow_bitmap = bm_load(Sun_bitmaps[idx].glow_filename);
2299 
2300  // maybe didn't load a static image so try for an animated one
2301  if (Sun_bitmaps[idx].glow_bitmap < 0) {
2302  Sun_bitmaps[idx].glow_bitmap = bm_load_animation(Sun_bitmaps[idx].glow_filename, &Sun_bitmaps[idx].glow_n_frames, &Sun_bitmaps[idx].glow_fps, NULL, 1);
2303 
2304  if (Sun_bitmaps[idx].glow_bitmap < 0) {
2305  Warning(LOCATION, "Unable to load sun glow bitmap: '%s'!\n", Sun_bitmaps[idx].glow_filename);
2306  }
2307  }
2308  }
2309 
2310  if (Sun_bitmaps[idx].flare) {
2311  for (i = 0; i < MAX_FLARE_BMP; i++) {
2312  flare_bitmap* fbp = &Sun_bitmaps[idx].flare_bitmaps[i];
2313  if ( !strlen(fbp->filename) )
2314  continue;
2315 
2316  if (fbp->bitmap_id < 0) {
2317  fbp->bitmap_id = bm_load(fbp->filename);
2318 
2319  if (fbp->bitmap_id < 0) {
2320  Warning(LOCATION, "Unable to load sun flare bitmap: '%s'!\n", Sun_bitmaps[idx].flare_bitmaps[i].filename);
2321  continue;
2322  }
2323  }
2324  }
2325  }
2326  }
2327 
2328  // now check if we can make use of a previously discarded instance entry
2329  // this should never happen with FRED
2330  if ( !Fred_running ) {
2331  for (i = 0; i < (int)Suns.size(); i++) {
2332  if ( Suns[i].star_bitmap_index < 0 ) {
2333  Suns[i] = sbi;
2334  return i;
2335  }
2336  }
2337  }
2338 
2339  // ... or add a new one
2340  Suns.push_back(sbi);
2341 
2342  return Suns.size() - 1;
2343 }
2344 
2345 // add an instance for a starfield bitmap (something actually used in a mission)
2346 // NOTE that we assume a duplicate is ok here
2348 {
2349  int idx;
2351 
2352  Assert(sle != NULL);
2353 
2354  // copy information
2355  sbi.ang.p = sle->ang.p;
2356  sbi.ang.b = sle->ang.b;
2357  sbi.ang.h = sle->ang.h;
2358  sbi.scale_x = sle->scale_x;
2359  sbi.scale_y = sle->scale_y;
2360  sbi.div_x = sle->div_x;
2361  sbi.div_y = sle->div_y;
2362 
2363  idx = stars_find_bitmap(sle->filename);
2364 
2365  if (idx == -1) {
2366  Warning(LOCATION, "Trying to add a bitmap '%s' that does not exist in stars.tbl!", sle->filename);
2367  return -1;
2368  }
2369 
2370  sbi.star_bitmap_index = idx;
2371 
2372  // make sure any needed bitmaps are loaded
2373  if (Starfield_bitmaps[idx].bitmap_id < 0) {
2374  Starfield_bitmaps[idx].bitmap_id = bm_load(Starfield_bitmaps[idx].filename);
2375 
2376  // maybe didn't load a static image so try for an animated one
2377  if (Starfield_bitmaps[idx].bitmap_id < 0) {
2378  Starfield_bitmaps[idx].bitmap_id = bm_load_animation(Starfield_bitmaps[idx].filename, &Starfield_bitmaps[idx].n_frames, &Starfield_bitmaps[idx].fps, NULL, 1);
2379 
2380  if (Starfield_bitmaps[idx].bitmap_id < 0) {
2381  // failed
2382  return -1;
2383  }
2384  }
2385  }
2386 
2387  // now check if we can make use of a previously discarded instance entry
2388  for (int i = 0; i < (int)Starfield_bitmap_instances.size(); i++) {
2389  if ( Starfield_bitmap_instances[i].star_bitmap_index < 0 ) {
2390  // starfield_update_index_buffers(i, 0);
2391  Starfield_bitmap_instances[i] = sbi;
2392  starfield_create_bitmap_buffer(i);
2393  return i;
2394  }
2395  }
2396 
2397  // ... or add a new one
2398  Starfield_bitmap_instances.push_back(sbi);
2399  starfield_create_bitmap_buffer(Starfield_bitmap_instances.size() - 1);
2400 
2401  return Starfield_bitmap_instances.size() - 1;
2402 }
2403 
2404 // get the number of entries that each vector contains
2405 // "is_a_sun" will get sun instance counts, otherwise it gets normal starfield bitmap instance counts
2406 // "bitmap_count" will get number of starfield_bitmap entries rather than starfield_bitmap_instance entries
2407 int stars_get_num_entries(bool is_a_sun, bool bitmap_count)
2408 {
2409  // try for instance counts first
2410  if (!bitmap_count) {
2411  if (is_a_sun) {
2412  return (int)Suns.size();
2413  } else {
2414  return (int)Starfield_bitmap_instances.size();
2415  }
2416  }
2417  // looks like we want bitmap counts (probably only FRED uses this)
2418  else {
2419  if (is_a_sun) {
2420  return (int)Sun_bitmaps.size();
2421  } else {
2422  return (int)Starfield_bitmaps.size();
2423  }
2424  }
2425 }
2426 
2427 
2428 // get a starfield_bitmap entry providing only an instance
2430 {
2431  int max_index = (is_a_sun) ? (int)Suns.size() : (int)Starfield_bitmap_instances.size();
2432 
2433  //WMC - Commented out because it keeps happening, and I don't know what this means.
2434  //Assert( (index >= 0) && (index < max_index) );
2435 
2436  if ( (index < 0) || (index >= max_index) )
2437  return NULL;
2438 
2439  if (is_a_sun && (Suns[index].star_bitmap_index >= 0)) {
2440  return &Sun_bitmaps[Suns[index].star_bitmap_index];
2441  } else if (!is_a_sun && (Starfield_bitmap_instances[index].star_bitmap_index >= 0)) {
2442  return &Starfield_bitmaps[Starfield_bitmap_instances[index].star_bitmap_index];
2443  }
2444 
2445  return NULL;
2446 }
2447 
2449 {
2450  starfield_bitmap *sb = stars_get_bitmap_entry(index, true);
2451  return (sb && sb->glare);
2452 }
2453 
2454 // get a starfield_bitmap_instance, obviously
2456 {
2457  int max_index = (is_a_sun) ? (int)Suns.size() : (int)Starfield_bitmap_instances.size();
2458 
2459  Assert( (index >= 0) && (index < max_index) );
2460 
2461  if ( (index < 0) || (index >= max_index) )
2462  return NULL;
2463 
2464  if (is_a_sun) {
2465  return &Suns[index];
2466  } else {
2467  return &Starfield_bitmap_instances[index];
2468  }
2469 }
2470 
2471 // set an instace to not render
2472 void stars_mark_instance_unused(int index, bool is_a_sun)
2473 {
2474  int max_index = (is_a_sun) ? (int)Suns.size() : (int)Starfield_bitmap_instances.size();
2475 
2476  Assert( (index >= 0) && (index < max_index) );
2477 
2478  if ( (index < 0) || (index >= max_index) )
2479  return;
2480 
2481  if (is_a_sun) {
2482  Suns[index].star_bitmap_index = -1;
2483  } else {
2484  Starfield_bitmap_instances[index].star_bitmap_index = -1;
2485  }
2486 
2487  if ( !is_a_sun ) {
2488  delete [] Starfield_bitmap_instances[index].verts;
2489  Starfield_bitmap_instances[index].verts = NULL;
2490  }
2491 }
2492 
2493 // retrieves the name from starfield_bitmap for the instance index
2494 // NOTE: it's unsafe to return NULL here so use <none> for invalid entries
2495 const char *stars_get_name_from_instance(int index, bool is_a_sun)
2496 {
2497  int max_index = (is_a_sun) ? (int)Suns.size() : (int)Starfield_bitmap_instances.size();
2498 
2499  Assert( (index >= 0) && (index < max_index) );
2500 
2501  if ( (index < 0) || (index >= max_index) )
2502  return NOX("<none>");
2503 
2504  if (is_a_sun && (Suns[index].star_bitmap_index >= 0)) {
2505  return Sun_bitmaps[Suns[index].star_bitmap_index].filename;
2506  } else if (!is_a_sun && (Starfield_bitmap_instances[index].star_bitmap_index >= 0)) {
2507  return Starfield_bitmaps[Starfield_bitmap_instances[index].star_bitmap_index].filename;
2508  }
2509 
2510  return NOX("<none>");
2511 }
2512 
2513 // WMC/Goober5000
2514 void stars_set_nebula(bool activate)
2515 {
2516  if (activate)
2517  {
2520  HUD_contrast = 1;
2521  if(Cmdline_nohtl || Fred_running) {
2525  } else {
2527  }
2528  Debris_vclips = Debris_vclips_nebula;
2529  neb2_eye_changed();
2530  }
2531  else
2532  {
2536  Debris_vclips = Debris_vclips_normal;
2537  HUD_contrast = 0;
2538  }
2539 }
2540 
2541 // retrieves the name from starfield_bitmap, really only used by FRED2
2542 // NOTE: it is unsafe to return NULL here, but because that's bad anyway it really shouldn't happen, so we do return NULL.
2543 const char *stars_get_name_FRED(int index, bool is_a_sun)
2544 {
2545  if (!Fred_running)
2546  return NULL;
2547 
2548  int max_index = (is_a_sun) ? (int)Sun_bitmaps.size() : (int)Starfield_bitmaps.size();
2549 
2550  Assert( (index >= 0) && (index < max_index) );
2551 
2552  if ( (index < 0) || (index >= max_index) )
2553  return NULL;
2554 
2555  if (is_a_sun) {
2556  return Sun_bitmaps[index].filename;
2557  } else {
2558  return Starfield_bitmaps[index].filename;
2559  }
2560 }
2561 
2562 // modify an existing starfield bitmap instance, or add a new one if needed
2563 void stars_modify_entry_FRED(int index, const char *name, starfield_list_entry *sbi_new, bool is_a_sun)
2564 {
2565  if (!Fred_running)
2566  return;
2567 
2569  int idx;
2570  int add_new = index > ((is_a_sun) ? (int)Sun_bitmaps.size() : (int)Starfield_bitmaps.size());
2571 
2572  Assert( index >= 0 );
2573  Assert( sbi_new != NULL );
2574 
2575  // copy information
2576  sbi.ang.p = sbi_new->ang.p;
2577  sbi.ang.b = sbi_new->ang.b;
2578  sbi.ang.h = sbi_new->ang.h;
2579  sbi.scale_x = sbi_new->scale_x;
2580  sbi.scale_y = sbi_new->scale_y;
2581  sbi.div_x = sbi_new->div_x;
2582  sbi.div_y = sbi_new->div_y;
2583 
2584  if (is_a_sun) {
2585  idx = stars_find_sun((char*)name);
2586  } else {
2587  idx = stars_find_bitmap((char*)name);
2588  }
2589 
2590  // this shouldn't ever happen from FRED since you select the name from a list of those available
2591  if (idx == -1)
2592  return;
2593 
2594  sbi.star_bitmap_index = idx;
2595 
2596  if (add_new) {
2597  if (is_a_sun) {
2598  Suns.push_back( sbi );
2599  } else {
2600  Starfield_bitmap_instances.push_back( sbi );
2601  }
2602  } else {
2603  if (is_a_sun) {
2604  Suns[index] = sbi;
2605  } else {
2606  Starfield_bitmap_instances[index] = sbi;
2607  }
2608  }
2609 
2610  if ( !is_a_sun ) {
2611  starfield_create_bitmap_buffer(index);
2612  }
2613 }
2614 
2615 // erase an instance, note that this is very slow so it should only be done in FRED
2616 void stars_delete_entry_FRED(int index, bool is_a_sun)
2617 {
2618  if (!Fred_running)
2619  return;
2620 
2621  int max_index = (is_a_sun) ? (int)Suns.size() : (int)Starfield_bitmap_instances.size();
2622 
2623  Assert( (index >= 0) && (index < max_index) );
2624 
2625  if ( (index < 0) || (index >= max_index) )
2626  return;
2627 
2628  if (is_a_sun) {
2629  Suns.erase( Suns.begin() + index );
2630  } else {
2631  Starfield_bitmap_instances.erase( Starfield_bitmap_instances.begin() + index );
2632  }
2633 }
2634 
2635 // Goober5000
2637 {
2638  int background_idx = stars_get_first_valid_background();
2639  stars_load_background(background_idx);
2640 }
2641 
2642 // Goober5000
2644 {
2645  uint i, j;
2646 
2647  if (Num_backgrounds == 0)
2648  return -1;
2649 
2650  // scan every background except the last and return the first one that has all its suns and bitmaps present
2651  for (i = 0; i < (uint)Num_backgrounds - 1; i++)
2652  {
2653  bool valid = true;
2654  background_t *background = &Backgrounds[i];
2655 
2656  for (j = 0; j < background->suns.size(); j++)
2657  {
2658  if (stars_find_sun(background->suns[j].filename) < 0)
2659  {
2660  mprintf(("Failed to load sun %s for background %d, falling back to background %d\n",
2661  background->suns[j].filename, i + 1, i + 2));
2662  valid = false;
2663  break;
2664  }
2665  }
2666 
2667  if (valid)
2668  {
2669  for (j = 0; j < background->bitmaps.size(); j++)
2670  {
2671  if (stars_find_bitmap(background->bitmaps[j].filename) < 0)
2672  {
2673  mprintf(("Failed to load bitmap %s for background %d, falling back to background %d\n",
2674  background->suns[j].filename, i + 1, i + 2));
2675  valid = false;
2676  break;
2677  }
2678  }
2679  }
2680 
2681  if (valid)
2682  return i;
2683  }
2684 
2685  // didn't find a valid background yet, so return the last one
2686  return Num_backgrounds - 1;
2687 }
2688 
2689 // Goober5000
2690 void stars_load_background(int background_idx)
2691 {
2692  uint j;
2693 
2695  Cur_background = background_idx;
2696 
2697  if (Cur_background >= 0)
2698  {
2699  background_t *background = &Backgrounds[Cur_background];
2700 
2701  int failed_suns = 0;
2702  for (j = 0; j < background->suns.size(); j++)
2703  {
2704  if ((stars_add_sun_entry(&background->suns[j]) < 0) && !Fred_running)
2705  {
2706  nprintf(("General", "Failed to add sun '%s' to the mission!", background->suns[j].filename));
2707  failed_suns++;
2708  }
2709  }
2710  if (failed_suns > 0)
2711  Warning(LOCATION, "Failed to add %d sun bitmaps to the mission!", failed_suns);
2712 
2713  int failed_stars = 0;
2714  for (j = 0; j < background->bitmaps.size(); j++)
2715  {
2716  if ((stars_add_bitmap_entry(&background->bitmaps[j]) < 0) && !Fred_running)
2717  {
2718  nprintf(("General", "Failed to add starfield bitmap '%s' to the mission!", background->bitmaps[j].filename));
2719  failed_stars++;
2720  }
2721  }
2722  if (failed_stars > 0)
2723  Warning(LOCATION, "Failed to add %d starfield bitmaps to the mission!", failed_stars);
2724  }
2725 }
2726 
2727 // Goober5000
2729 {
2730  dest->suns.assign(src->suns.begin(), src->suns.end());
2731  dest->bitmaps.assign(src->bitmaps.begin(), src->bitmaps.end());
2732 }
2733 
2734 // Goober5000
2735 void stars_swap_backgrounds(int idx1, int idx2)
2736 {
2738  stars_copy_background(&temp, &Backgrounds[idx1]);
2739  stars_copy_background(&Backgrounds[idx1], &Backgrounds[idx2]);
2740  stars_copy_background(&Backgrounds[idx2], &temp);
2741 }
2742 
2743 // Goober5000
2745 {
2746  return !(Backgrounds[idx].suns.size() > 0 || Backgrounds[idx].bitmaps.size() > 0);
2747 }
2748 
2749 // Goober5000
2751 {
2752  int i, j;
2753 
2754  // move all empty entries to the end, and recount
2755  Num_backgrounds = 0;
2756  for (i = 0; i < MAX_BACKGROUNDS; i++)
2757  {
2758  if (!stars_background_empty(i))
2759  {
2760  Num_backgrounds++;
2761  continue;
2762  }
2763 
2764  for (j = i + 1; j < MAX_BACKGROUNDS; j++)
2765  {
2766  if (!stars_background_empty(j))
2767  {
2768  stars_swap_backgrounds(i, j);
2769  Num_backgrounds++;
2770  break;
2771  }
2772  }
2773  }
2774 }
void light_add_directional(const vec3d *dir, float intensity, float r, float g, float b, float spec_r, float spec_g, float spec_b, bool specular)
Definition: lighting.cpp:209
fix starfield_timestamp
Definition: starfield.cpp:59
void advance_to_eoln(char *more_terminators)
Definition: parselo.cpp:335
int stars_get_num_entries(bool is_a_sun, bool bitmap_count)
Definition: starfield.cpp:2407
float Subspace_glow_frame
Definition: starfield.cpp:1310
#define MAX_FILENAME_LEN
Definition: pstypes.h:324
matrix skybox_orientation
Definition: missionparse.h:148
#define gr_zbuffer_set
Definition: 2d.h:817
int timestamp(int delta_ms)
Definition: timer.cpp:226
char Neb2_texture_name[MAX_FILENAME_LEN]
Definition: neb.cpp:75
struct screen3d::@234::@236 xyw
int Num_debris_normal
Definition: starfield.cpp:172
matrix Nmodel_orient
Definition: starfield.cpp:168
int i
Definition: multi_pxo.cpp:466
fix Missiontime
Definition: systemvars.cpp:19
#define NEB2_RENDER_HTL
Definition: neb.h:35
int stars_add_bitmap_entry(starfield_list_entry *sle)
Definition: starfield.cpp:2347
int n_textures
Definition: model.h:761
float p
Definition: pstypes.h:111
void stars_draw_debris()
Definition: starfield.cpp:1738
SCP_vector< starfield_list_entry > suns
Definition: starfield.h:40
#define TMAP_FLAG_XPARENT
Definition: tmapper.h:44
float subspace_offset_v
Definition: starfield.cpp:1303
int Nmodel_flags
Definition: starfield.cpp:169
float vm_vec_mag_quick(const vec3d *v)
Definition: vecmat.cpp:371
int Neb2_render_mode
Definition: neb.cpp:57
#define DETAIL_FLAG_MOTION
Definition: systemvars.h:109
float supernova_pct_complete()
Definition: supernova.cpp:285
float Interp_subspace_offset_u
Definition: starfield.cpp:1298
void stars_release_debris_vclips(debris_vclip *vclips)
Definition: starfield.cpp:178
#define STAR_FLAG_TAIL
Definition: starfield.cpp:869
#define MISSION_FLAG_FULLNEB
Definition: missionparse.h:70
#define DEBRIS_ROT_RANGE
Definition: starfield.cpp:33
int div_y
Definition: starfield.h:33
polymodel * model_get(int model_num)
Definition: modelread.cpp:3134
float v
Definition: pstypes.h:135
float Star_max_length
Definition: starfield.cpp:867
const char * stars_get_name_FRED(int index, bool is_a_sun)
Definition: starfield.cpp:2543
background_t Backgrounds[MAX_BACKGROUNDS]
Definition: starfield.cpp:125
float flFrametime
Definition: fredstubs.cpp:22
float subspace_offset_u
Definition: starfield.cpp:1301
#define gr_set_texture_panning
Definition: 2d.h:934
GLsizei const GLfloat * value
Definition: Glext.h:5646
int mode
Definition: 2d.h:371
#define MR_ALL_XPARENT
Definition: model.h:877
bool Motion_debris_override
Definition: starfield.cpp:176
GLuint index
Definition: Glext.h:5608
int Fred_running
Definition: fred.cpp:44
matrix * vm_angles_2_matrix(matrix *m, const angles *a)
Definition: vecmat.cpp:752
#define gr_start_instance_matrix
Definition: 2d.h:899
#define STAR_FLAG_ANTIALIAS
Definition: starfield.cpp:871
void stars_set_nebula(bool activate)
Definition: starfield.cpp:2514
void stars_set_background_orientation(matrix *orient)
Definition: starfield.cpp:2207
void stars_mark_instance_unused(int index, bool is_a_sun)
Definition: starfield.cpp:2472
#define DEFAULT_NMODEL_FLAGS
Definition: starfield.h:20
debris_vclip Debris_vclips_normal[]
Definition: starfield.cpp:157
#define TOGGLE_TEXT_NORMAL_ALPHA
Definition: hudtarget.h:57
#define DETAIL_FLAG_STARS
Definition: systemvars.h:107
ubyte g3_transfer_vertex(vertex *dest, const vec3d *src)
Definition: 3dmath.cpp:84
starfield_bitmap_instance * stars_get_instance(int index, bool is_a_sun)
Definition: starfield.cpp:2455
void _cdecl void void _cdecl void _cdecl Warning(char *filename, int line, SCP_FORMAT_STRING const char *format,...) SCP_FORMAT_STRING_ARGS(3
Assert(pm!=NULL)
struct vDist vDist
Definition: pstypes.h:88
float Star_dim
Definition: starfield.cpp:865
#define mprintf(args)
Definition: pstypes.h:238
void gr_init_alphacolor(color *clr, int r, int g, int b, int alpha, int type)
Definition: 2d.cpp:1173
struct flare_info flare_info
int Toggle_text_alpha
Definition: hudtarget.cpp:226
Definition: 2d.h:95
void stars_preload_sun_bitmap(char *fname)
Definition: starfield.cpp:1873
matrix Eye_matrix
Definition: 3dsetup.cpp:26
#define gr_render
Definition: 2d.h:805
int HUD_contrast
Definition: hud.cpp:79
void stars_pre_level_init(bool clear_backgrounds)
Definition: starfield.cpp:714
void set_flags(uint flags)
#define MR_NO_LIGHTING
Definition: model.h:867
int light_get_global_dir(vec3d *pos, int n)
Definition: lighting.cpp:621
struct vec3d::@225::@227 xyz
bool stars_background_empty(int idx)
Definition: starfield.cpp:2744
#define TMAP_HTL_3D_UNLIT
Definition: tmapper.h:63
int skybox_flags
Definition: missionparse.h:150
void model_render_immediate(model_render_params *render_info, int model_num, matrix *orient, vec3d *pos, int render, bool sort)
const float MIN_DIST_RANGE
Definition: starfield.cpp:50
uint Star_flags
Definition: starfield.cpp:874
GLclampf f
Definition: Glext.h:7097
#define GR_ZBUFF_NONE
Definition: 2d.h:672
old_debris odebris[MAX_DEBRIS]
Definition: starfield.cpp:144
int Nmodel_instance_num
Definition: starfield.cpp:167
#define STAR_MAX_LENGTH_DEFAULT
Definition: starfield.cpp:862
vec3d * vm_vec_rotate(vec3d *dest, const vec3d *src, const matrix *m)
Definition: vecmat.cpp:933
float BASE_SIZE_NEB
Definition: starfield.cpp:52
float pos
Definition: starfield.cpp:65
#define f2fl(fx)
Definition: floating.h:37
vec3d pos
Definition: starfield.cpp:132
ubyte g3_code_vertex(vertex *point)
Definition: 3dmath.cpp:54
void stars_copy_background(background_t *dest, background_t *src)
Definition: starfield.cpp:2728
const int RAND_MAX_2
Definition: pstypes.h:308
dc_stuff_int & val_i
Definition: multilag.cpp:582
void gr_set_color_fast(color *dst)
Definition: 2d.cpp:1197
#define gr_end_instance_matrix
Definition: 2d.h:901
hull_check orient
Definition: lua.cpp:5049
std::basic_string< char, std::char_traits< char >, std::allocator< char > > SCP_string
Definition: vmallocator.h:21
#define MAX_DEBRIS_VCLIPS
Definition: starfield.cpp:31
float subspace_offset_u_inner
Definition: starfield.cpp:1302
void gr_set_bitmap(int bitmap_num, int alphablend_mode, int bitblt_mode, float alpha)
Definition: 2d.cpp:2105
GLsizeiptr size
Definition: Glext.h:5496
debris_vclip * Debris_vclips
Definition: starfield.cpp:159
#define Int3()
Definition: pstypes.h:292
int stars_get_first_valid_background()
Definition: starfield.cpp:2643
void stars_modify_entry_FRED(int index, const char *name, starfield_list_entry *sbi_new, bool is_a_sun)
Definition: starfield.cpp:2563
#define AC_TYPE_BLEND
Definition: 2d.h:90
float Noise[NOISE_NUM_FRAMES]
Definition: systemvars.cpp:83
void bm_page_in_xparent_texture(int bitmapnum, int nframes)
Marks a textures as being used for level and is transparant.
Definition: bmpman.cpp:2514
int bm_release(int handle, int clear_render_targets)
Frees both a bitmap's data and it's associated slot.
Definition: bmpman.cpp:2603
#define GR_OPENGL
Definition: 2d.h:648
#define TOGGLE_TEXT_NEBULA_ALPHA
Definition: hudtarget.h:56
int Cur_background
Definition: starfield.cpp:124
void stars_draw_sun(int show_sun)
Definition: starfield.cpp:1038
char filename[MAX_FILENAME_LEN]
Definition: starfield.cpp:71
int div_x
Definition: starfield.h:33
void stars_draw_background()
Definition: starfield.cpp:2153
void stuff_float(float *f)
Definition: parselo.cpp:2328
int bm_load_animation(const char *real_filename, int *nframes, int *fps, int *keyframe, int can_drop_frames, int dir_type)
Loads a bitmap sequance so we can draw with it.
Definition: bmpman.cpp:1420
#define CLAMP(x, min, max)
Definition: pstypes.h:488
int Num_backgrounds
Definition: starfield.cpp:123
#define STAR_FLAG_DIM
Definition: starfield.cpp:870
void gr_set_color(int r, int g, int b)
Definition: 2d.cpp:1188
const int MAX_STARS
Definition: starfield.cpp:47
#define MR_SKYBOX
Definition: model.h:860
uv_pair texture_position
Definition: pstypes.h:174
int Cmdline_nomotiondebris
Definition: cmdline.cpp:327
int y
Definition: starfield.cpp:139
void set_alpha(float alpha)
star Stars[MAX_STARS]
Definition: starfield.cpp:142
#define PM_FLAG_HAS_INTRINSIC_ROTATE
Definition: model.h:624
float scale_x
Definition: starfield.h:32
void stars_preload_background_bitmap(char *fname)
Definition: starfield.cpp:1889
typedef int(SCP_EXT_CALLCONV *SCPDLL_PFVERSION)(SCPDLL_Version *)
float scale
Definition: starfield.cpp:66
float Star_amount
Definition: starfield.cpp:864
const float MAX_DIST
Definition: starfield.cpp:48
int Num_stars
Definition: starfield.cpp:58
angles ang
Definition: starfield.h:34
#define PF_OVERFLOW
Definition: 3d.h:22
#define NEB2_RENDER_LAME
Definition: neb.h:34
#define DEBRIS_ROT_MIN
Definition: starfield.cpp:32
void vm_vec_add2(vec3d *dest, const vec3d *src)
Definition: vecmat.cpp:178
int Cmdline_nohtl
Definition: cmdline.cpp:438
#define GR_ALPHABLEND_FILTER
Definition: 2d.h:349
const float PI2
Definition: pstypes.h:305
#define SUPERNOVA_SUN_SCALE
Definition: supernova.h:29
int Game_subspace_effect
Definition: fredstubs.cpp:163
void model_delete_instance(int model_instance_num)
Definition: modelread.cpp:2907
float Interp_subspace_offset_v
struct matrix::@228::@230 vec
unsigned int uint
Definition: pstypes.h:64
screen3d screen
Definition: pstypes.h:173
void stars_set_background_model(char *model_name, char *texture_name, int flags)
Definition: starfield.cpp:2172
void vm_vec_scale(vec3d *dest, float s)
Definition: vecmat.cpp:248
#define nprintf(args)
Definition: pstypes.h:239
#define MAX_BACKGROUNDS
Definition: starfield.h:43
void stars_load_background(int background_idx)
Definition: starfield.cpp:2690
struct starfield_bitmap_instance starfield_bitmap_instance
detail_levels Detail
Definition: systemvars.cpp:478
void stars_post_level_init()
Definition: starfield.cpp:782
GLboolean GLboolean GLboolean GLboolean a
Definition: Glext.h:5781
#define STAR_FLAG_DEFAULT
Definition: starfield.cpp:872
GLclampf GLclampf blue
Definition: Glext.h:5177
void neb2_eye_changed()
Definition: neb.cpp:1111
#define gr_draw_line_list
Definition: 2d.h:936
int Nmodel_num
Definition: starfield.cpp:166
float g3_draw_laser(const vec3d *headp, float head_width, const vec3d *tailp, float tail_width, uint tmap_flags=TMAP_FLAG_TEXTURED, float max_len=0.0f)
Definition: 3dlaser.cpp:116
int last_stars_filled
Definition: starfield.cpp:127
char * filename
vec3d vec
Definition: 2d.h:176
const float p_theta
Definition: starfield.cpp:238
texture_map maps[MAX_MODEL_TEXTURES]
Definition: model.h:762
flare_info flare_infos[MAX_FLARE_COUNT]
Definition: starfield.cpp:90
color star_aacolors[8]
Definition: starfield.cpp:129
struct color color
Definition: Glext.h:6943
void stars_draw_sun_glow(int sun_n)
Definition: starfield.cpp:1154
void stuff_string(char *outstr, int type, int len, char *terminators)
Definition: parselo.cpp:1189
void stars_load_debris_vclips(debris_vclip *vclips)
Definition: starfield.cpp:193
void stars_close()
Definition: starfield.cpp:706
int stars_find_bitmap(char *name)
Definition: starfield.cpp:2217
#define STAR_AMOUNT_DEFAULT
Definition: starfield.cpp:859
#define CF_TYPE_TABLES
Definition: cfile.h:50
sprintf(buf,"(%f,%f,%f)", v3->xyz.x, v3->xyz.y, v3->xyz.z)
void vm_set_identity(matrix *m)
Definition: vecmat.cpp:150
#define MAX_FLARE_BMP
Definition: starfield.cpp:62
int Stars_background_inited
Definition: starfield.cpp:165
ubyte red
Definition: 2d.h:100
int stars_find_sun(char *name)
Definition: starfield.cpp:2236
ubyte g3_rotate_vertex(vertex *dest, const vec3d *src)
Definition: 3dmath.cpp:97
hull_check p1
Definition: lua.cpp:5052
int required_string(const char *pstr)
Definition: parselo.cpp:468
debris_vclip Debris_vclips_nebula[]
Definition: starfield.cpp:158
void stars_project_2d_onto_sphere(vec3d *pnt, float rho, float phi, float theta)
Definition: 3ddraw.cpp:1419
float u
Definition: pstypes.h:135
const int MAX_DEBRIS
Definition: starfield.cpp:46
int optional_string(const char *pstr)
Definition: parselo.cpp:539
char skybox_model[MAX_FILENAME_LEN]
Definition: missionparse.h:147
bool dc_optional_string_either(const char *str1, const char *str2)
Searches for an optional string and it's alias.
int Subspace_glow_bitmap
Definition: starfield.cpp:1308
object * Player_obj
Definition: object.cpp:56
#define NEB2_RENDER_POF
Definition: neb.h:33
int model_load(char *filename, int n_subsystems, model_subsystem *subsystems, int ferror=1, int duplicate=0)
Definition: modelread.cpp:2573
void read_file_text(const char *filename, int mode, char *processed_text, char *raw_text)
Definition: parselo.cpp:1995
color col
Definition: starfield.cpp:134
void model_page_in_textures(int modelnum, int ship_info_index=-1)
bool Parsing_modular_table
Definition: parselo.cpp:34
void set_color(color &clr)
int clip_bottom
Definition: 2d.h:388
int g3_project_vertex(vertex *point)
Definition: 3dmath.cpp:202
int idx
Definition: multiui.cpp:761
GLclampf green
Definition: Glext.h:5177
vec3d pos
Definition: starfield.cpp:39
int clip_top
Definition: 2d.h:388
void set_forced_bitmap(int bitmap)
#define MODEL_RENDER_ALL
Definition: model.h:935
long fix
Definition: pstypes.h:54
unsigned char ubyte
Definition: pstypes.h:62
void stars_swap_backgrounds(int idx1, int idx2)
Definition: starfield.cpp:2735
void stars_draw_stars()
Definition: starfield.cpp:1646
void stars_camera_cut()
Definition: starfield.cpp:1005
starfield_bitmap * stars_get_bitmap_entry(int index, bool is_a_sun)
Definition: starfield.cpp:2429
#define gr_set_cull
Definition: 2d.h:838
#define NOX(s)
Definition: pstypes.h:473
void _cdecl void void _cdecl Error(const char *filename, int line, SCP_FORMAT_STRING const char *format,...) SCP_FORMAT_STRING_ARGS(3
#define STAR_CAP_DEFAULT
Definition: starfield.cpp:861
#define TMAP_FLAG_CORRECT
Definition: tmapper.h:37
void dc_stuff_float(float *f)
Stuffs a float to the given variable.
ubyte flags
Definition: pstypes.h:178
GLbitfield flags
Definition: Glext.h:6722
#define gr_aaline
Definition: 2d.h:796
void reset_parse(char *text)
Definition: parselo.cpp:3305
#define CHECK_END()
Definition: starfield.cpp:395
void dc_stuff_int(int *i)
Stuffs an int to the given variable. Supports binary (0b), hexadecimal (0x), and octal (0o) formats...
GLuint const GLchar * name
Definition: Glext.h:5608
void stars_load_first_valid_background()
Definition: starfield.cpp:2636
#define IDENTITY_MATRIX
Definition: vecmat.h:64
void vm_vec_sub(vec3d *dest, const vec3d *src0, const vec3d *src1)
Definition: vecmat.cpp:168
void stars_load_debris(int fullneb=0)
Definition: starfield.cpp:217
vec3d Eye_position
Definition: 3dsetup.cpp:27
void dc_stuff_string_white(char *out_str, size_t maxlen)
Stuffs a whitespace delimited string to out_str from the command line, stopping at the end of the com...
int bm_load(const char *real_filename)
Loads a bitmap so we can draw with it later.
Definition: bmpman.cpp:1119
void stuff_int(int *i)
Definition: parselo.cpp:2372
__inline void gr_fog_set(int fog_mode, int r, int g, int b, float fog_near=-1.0f, float fog_far=-1.0f)
Definition: 2d.h:833
uint Game_detail_flags
Definition: systemvars.cpp:52
int clip_right
Definition: 2d.h:388
bool Nebula_sexp_used
Definition: neb.cpp:34
#define TMAP_FLAG_TRILIST
Definition: tmapper.h:68
typedef float(SCP_EXT_CALLCONV *SCPTRACKIR_PFFLOATVOID)()
struct starfield_bitmap starfield_bitmap
flare_bitmap flare_bitmaps[MAX_FLARE_BMP]
Definition: starfield.cpp:91
void stars_get_sun_pos(int sun_n, vec3d *pos)
Definition: starfield.cpp:1016
ubyte g3_rotate_faraway_vertex(vertex *dest, const vec3d *src)
Definition: 3dmath.cpp:156
vec3d last_pos
Definition: starfield.cpp:40
float vm_vec_dist_quick(const vec3d *v0, const vec3d *v1)
Definition: vecmat.cpp:417
const int MAX_PERSPECTIVE_DIVISIONS
Definition: starfield.cpp:237
int Num_debris_nebula
Definition: starfield.cpp:173
#define HALF_RND_MAX
Definition: starfield.cpp:36
int optional_string_either(char *str1, char *str2)
Definition: parselo.cpp:551
#define fl2i(fl)
Definition: floating.h:33
void bm_page_in_texture(int bitmapnum, int nframes)
Marks a texture as being used for this level.
Definition: bmpman.cpp:2462
fix timer_get_fixed_seconds()
Definition: timer.cpp:116
void subspace_render()
Definition: starfield.cpp:1359
#define RND_MAX_MASK
Definition: starfield.cpp:35
const float p_phi
Definition: starfield.cpp:238
screen gr_screen
Definition: 2d.cpp:46
bool Dynamic_environment
Definition: starfield.cpp:175
ubyte color[4]
Definition: 2d.h:178
float vm_vec_copy_normalize(vec3d *dest, const vec3d *src)
Definition: vecmat.cpp:427
float scale_y
Definition: starfield.h:32
float Subspace_glow_rate
Definition: starfield.cpp:1311
DCF(stars,"Set parameters for starfield")
Definition: starfield.cpp:877
void stars_draw(int show_stars, int show_suns, int show_nebulas, int show_subspace, int env)
Definition: starfield.cpp:1813
GLfloat GLfloat p
Definition: Glext.h:8373
#define F_NAME
Definition: parselo.h:34
An overhauled/updated debug console to allow monitoring, testing, and general debugging of new featur...
void parse_startbl(const char *filename)
Definition: starfield.cpp:403
GLenum src
Definition: Glext.h:5917
#define LOCATION
Definition: pstypes.h:245
#define TMAP_FLAG_TEXTURED
Definition: tmapper.h:36
char filename[MAX_FILENAME_LEN]
Definition: starfield.cpp:78
struct debris_vclip debris_vclip
const char * stars_get_name_from_instance(int index, bool is_a_sun)
Definition: starfield.cpp:2495
#define STAR_DIM_DEFAULT
Definition: starfield.cpp:860
int g3_draw_bitmap(vertex *pos, int orient, float radius, uint tmap_flags, float depth=0.0f)
Definition: 3ddraw.cpp:649
hull_check pos
Definition: lua.cpp:5050
bool stars_sun_has_glare(int index)
Definition: starfield.cpp:2448
const GLfloat * m
Definition: Glext.h:10319
float subspace_v_speed
Definition: starfield.cpp:1306
struct flare_bitmap flare_bitmap
float vm_vec_dot(const vec3d *v0, const vec3d *v1)
Definition: vecmat.cpp:312
#define i2fl(i)
Definition: floating.h:32
void stars_page_in()
Definition: starfield.cpp:1905
int parse_modular_table(const char *name_check, void(*parse_callback)(const char *filename), int path_type, int sort_type)
Definition: parselo.cpp:4205
#define GR_BITBLT_MODE_NORMAL
Definition: 2d.h:351
int check_for_eof()
Definition: parselo.cpp:492
#define DETAIL_FLAG_NEBULAS
Definition: systemvars.h:108
vec3d world
Definition: pstypes.h:172
int temp
Definition: lua.cpp:4996
float val_f
Definition: multilag.cpp:561
void dc_printf(const char *format,...)
Prints the given char string to the debug console.
Definition: console.cpp:358
SCP_vector< starfield_list_entry > bitmaps
Definition: starfield.h:39
polymodel * pm
Definition: lua.cpp:1598
const float MAX_DIST_RANGE
Definition: starfield.cpp:49
cmdline_parm env("-noenv", NULL, AT_NONE)
#define NEB2_RENDER_NONE
Definition: neb.h:31
Definition: starfield.h:30
void nebula_render()
Definition: nebula.cpp:165
int bm_unload(int handle, int clear_render_targets, bool nodebug)
Unloads a bitmap's data, but not the bitmap info.
Definition: bmpman.cpp:2890
float subspace_u_speed
Definition: starfield.cpp:1305
int clip_left
Definition: 2d.h:388
float size
Definition: starfield.cpp:43
void stars_pack_backgrounds()
Definition: starfield.cpp:2750
ubyte codes
Definition: pstypes.h:177
char filename[MAX_FILENAME_LEN]
Definition: starfield.h:31
char glow_filename[MAX_FILENAME_LEN]
Definition: starfield.cpp:79
#define gr_zbuffer_get
Definition: 2d.h:816
int model_create_instance(bool is_ship, int model_num)
Definition: modelread.cpp:2855
int stars_debris_loaded
Definition: starfield.cpp:162
mission The_mission
const float BASE_SIZE
Definition: starfield.cpp:51
int supernova_active()
Definition: supernova.cpp:240
int Nmodel_bitmap
Definition: starfield.cpp:170
float h
Definition: pstypes.h:111
int x
Definition: starfield.cpp:138
#define MAX_DETAIL_LEVEL
Definition: systemvars.h:159
void stars_clear_instances()
Definition: starfield.cpp:681
GLclampf GLclampf GLclampf alpha
Definition: Glext.h:5177
void stars_init()
Definition: starfield.cpp:693
struct star star
vec3d vmd_zero_vector
Definition: vecmat.cpp:24
void stars_delete_entry_FRED(int index, bool is_a_sun)
Definition: starfield.cpp:2616
#define NOISE_NUM_FRAMES
Definition: systemvars.h:130
void stars_draw_bitmaps(int show_bitmaps)
Definition: starfield.cpp:1222
float Star_cap
Definition: starfield.cpp:866
#define stricmp(s1, s2)
Definition: config.h:271
void vm_vec_add(vec3d *dest, const vec3d *src0, const vec3d *src1)
Definition: vecmat.cpp:159
const GLdouble * v
Definition: Glext.h:5322
void gr_init_color(color *c, int r, int g, int b)
Definition: 2d.cpp:1155
matrix vmd_identity_matrix
Definition: vecmat.cpp:28
int Interp_subspace
int reload_old_debris
Definition: starfield.cpp:1001
#define MAX_FLARE_COUNT
Definition: starfield.cpp:61
void stars_load_all_bitmaps()
Definition: starfield.cpp:596
int myrand()
Definition: systemvars.cpp:102
vec3d last_star_pos
Definition: starfield.cpp:133
int stars_add_sun_entry(starfield_list_entry *sun_ptr)
Definition: starfield.cpp:2256
#define DEBRIS_ROT_RANGE_SCALER
Definition: starfield.cpp:34
float b
Definition: pstypes.h:111
void model_unload(int modelnum, int force=0)
Definition: modelread.cpp:162
#define BACKGROUND_MODEL_FILENAME
Definition: starfield.h:26
float vm_vec_normalize(vec3d *v)
Definition: vecmat.cpp:460
#define fl_radians(fl)
Definition: floating.h:42
#define GR_FOGMODE_NONE
Definition: 2d.h:355
#define strcpy_s(...)
Definition: safe_strings.h:67
color star_colors[8]
Definition: starfield.cpp:128
int Sun_drew
Definition: fredstubs.cpp:31
void stars_draw_lens_flare(vertex *sun_vex, int sun_n)
Definition: starfield.cpp:1104
#define NEB2_RENDER_POLY
Definition: neb.h:32