Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
165 changes: 165 additions & 0 deletions code/def_files/data/tables/generated_nebula.tbl
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
;; Generated background nebula (the modern FS1-style nebula a mission picks with +Nebula: and
;; +Color:). Mods replace this whole table with their own generated_nebula.tbl, or add to and
;; override it by name with *-gneb.tbm files.

#Generated Nebula Colors

;; +RGB: the color of the brightest parts; dimmer parts fade evenly toward black.
;; +Palette Suffix: with a pattern's +Palette Prefix: names an FS1 palette file (<prefix>-<suffix>.pcx);
;; when that file exists its first 20 entries are the ramp instead of the RGB fade. Retail FS2 ships
;; only gamepalette1-01 (Nebula01 Red); the others are FS1 data a mod can ship.
;; The built-in colors are FS1's: each FS1 mission palette held a 20-step ramp from black
;; to one color, and +RGB is that ramp's brightest entry.

$Name: Red
+RGB: 151 0 0
+Palette Suffix: 01

$Name: Blue
+RGB: 0 55 183
+Palette Suffix: 02

$Name: Gold
+RGB: 107 91 27
+Palette Suffix: 03

$Name: Purple
+RGB: 107 0 95
+Palette Suffix: 04

$Name: Maroon
+RGB: 107 0 39
+Palette Suffix: 05

$Name: Green
+RGB: 0 95 0
+Palette Suffix: 06

$Name: Grey blue
+RGB: 0 67 91
+Palette Suffix: 07

$Name: Violet
+RGB: 63 51 79
+Palette Suffix: 08

$Name: Grey Green
+RGB: 0 87 63
+Palette Suffix: 09

#End

#Generated Nebula Patterns

;; A pattern has two layers, combined so the clouds brighten the background without clipping:
;; - a procedural background made from noise (+Density through +Seed), unless +Clouds Only
;; - placed clouds (+Cloud), broken up by the same noise according to +Cloud Detail
;;
;; Fields, all optional, in this order:
;; +Mesh: an FS1 .neb mesh (nebula01-03 ship in sparky_fs2.vp); drawn through the color ramp
;; instead of the generated layers when the file exists, else the layers below are used
;; +Palette Prefix: see +Palette Suffix: under the colors
;; +Clouds Only: YES for no procedural background, only the placed clouds
;; +Cloud Detail: how much the noise breaks up the clouds, 0 (smooth) to 1 (ragged)
;; +Cloud: lon lat width height angle brightness, repeated for each cloud
;; lon/lat: center in degrees (lon 0..360 wraps, lat -90..90)
;; width/height: size in degrees of longitude, across and along the cloud
;; (full width at half brightness); angle: rotation in degrees
;; brightness: peak, 0..1 (overlapping clouds add up, capped at 1)
;; +Density: background: fraction of the sky with bright patches
;; +Frequency: noise frequency around and along the sphere (unequal values give streaks)
;; +Octaves: noise detail layers; fewer gives broader, smoother masses
;; +Warp: how much the noise is swirled, stretching it into wisps
;; +Contrast: background falloff curve for the bright patches
;; +Intensity: overall brightness multiplier (through a palette file, colors stop at its last entry)
;; +Seed: noise seed, giving each pattern its own variation
;; +Resolution: sphere mesh resolution (around, along)
;; +Band: range of the sphere covered, 0..1 from pole to pole
;;
;; The built-in patterns are clouds only, laid out to match the FS1 originals.

$Name: Nebula01
+Mesh: nebula01
+Palette Prefix: gamepalette1
+Clouds Only: YES
+Cloud Detail: 0.35
+Cloud: 222.7 -14.5 70.8 11.0 164 0.73
+Cloud: 136.6 -48.5 41.1 8.7 4 0.55
+Cloud: 217.5 36.7 60.6 10.4 6 0.46
+Cloud: 255.5 -4.0 44.3 22.1 155 0.87
+Cloud: 291.1 4.2 56.7 9.3 2 0.53
+Cloud: 160.1 -2.3 36.2 18.5 176 0.75
+Cloud: 93.4 2.4 53.0 18.7 8 0.42
+Cloud: 313.9 -8.7 46.5 8.7 13 0.39
+Cloud: 288.0 42.2 33.6 12.4 175 0.54
+Cloud: 188.6 -13.5 37.5 8.7 159 0.53
+Cloud: 110.0 -9.7 48.1 13.5 167 0.72
+Cloud: 109.6 -47.1 22.5 11.3 14 0.35
+Cloud: 274.3 -23.7 35.8 17.3 13 0.26
+Cloud: 152.6 -42.3 9.1 10.7 126 0.27
+Cloud: 228.5 2.6 36.6 14.0 10 0.29
+Cloud: 153.5 -9.2 34.0 10.4 4 0.37
+Cloud: 83.0 -11.5 33.6 10.0 8 0.31
+Cloud: 163.0 -47.2 34.9 6.0 14 0.24
+Frequency: 5 6
+Warp: 0.40
+Seed: 1
+Resolution: 48 20

$Name: Nebula02
+Mesh: nebula02
+Palette Prefix: gamepalette2
+Clouds Only: YES
+Cloud Detail: 0.35
+Cloud: 319.0 16.8 37.5 21.3 16 0.41
+Cloud: 85.4 -29.5 70.4 15.3 18 0.74
+Cloud: 54.1 11.0 36.4 8.0 5 0.36
+Cloud: 282.6 35.4 87.2 13.1 7 0.63
+Cloud: 253.5 23.9 34.4 19.1 167 0.88
+Cloud: 106.4 -15.1 46.4 12.7 1 0.61
+Cloud: 253.3 -37.9 101.6 9.1 3 0.44
+Cloud: 104.9 13.7 43.3 8.2 15 0.55
+Cloud: 212.1 3.1 43.0 19.9 14 0.50
+Cloud: 215.3 32.6 40.2 7.8 170 0.44
+Cloud: 67.4 16.9 24.7 18.8 7 0.47
+Cloud: 173.1 -2.7 40.2 11.8 34 0.64
+Cloud: 316.3 -30.5 27.2 14.9 15 0.28
+Cloud: 260.4 5.1 70.9 12.7 170 0.59
+Cloud: 284.0 12.2 41.7 8.5 171 0.61
+Cloud: 176.9 -7.1 51.9 4.7 27 0.39
+Cloud: 50.3 24.9 25.2 7.8 127 0.33
+Cloud: 98.1 -32.5 11.7 20.8 85 0.29
+Frequency: 6 5
+Warp: 0.50
+Seed: 2
+Resolution: 48 20

$Name: Nebula03
+Mesh: nebula03
+Palette Prefix: gamepalette3
+Clouds Only: YES
+Cloud Detail: 0.35
+Cloud: 257.6 31.6 33.8 18.2 14 0.85
+Cloud: 123.8 -11.5 62.7 10.9 13 0.67
+Cloud: 106.1 14.6 42.9 9.0 1 0.63
+Cloud: 323.7 13.7 34.7 19.6 9 0.54
+Cloud: 121.3 39.9 45.5 12.7 1 0.47
+Cloud: 72.6 -46.4 55.4 12.2 177 0.86
+Cloud: 100.6 -17.8 67.1 15.0 173 0.48
+Cloud: 239.8 -38.1 64.7 9.3 2 0.38
+Cloud: 301.4 35.2 56.2 11.4 5 0.73
+Cloud: 98.4 -37.4 32.0 18.2 145 0.57
+Cloud: 126.0 -53.5 37.8 6.9 4 0.31
+Cloud: 52.9 17.8 37.1 7.4 174 0.52
+Cloud: 259.1 22.1 42.8 10.0 1 0.65
+Cloud: 67.1 17.5 33.8 8.5 16 0.37
+Cloud: 172.0 40.6 39.5 12.9 6 0.64
+Cloud: 126.4 -24.3 57.2 10.9 9 0.31
+Cloud: 306.4 6.7 35.8 10.7 0 0.43
+Cloud: 301.1 -33.1 38.6 8.9 1 0.28
+Frequency: 5 7
+Warp: 0.60
+Seed: 3
+Resolution: 48 20

#End
48 changes: 20 additions & 28 deletions code/lab/renderer/lab_renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -380,13 +380,15 @@ void LabRenderer::useBackground(const SCP_string& mission_name) {
int skybox_flags;

int ambient_light_level;
extern const char* Neb2_filenames[];

char envmap_name[MAX_FILENAME_LEN] = {0};
SCP_string ltp_name;
currentMissionBackground = mission_name;

stars_pre_level_init(true);
nebula_close();
Nebula_index = -1;
Nebula_mission_switch = -1;
vm_set_identity(&skybox_orientation);

// (DahBlount) - Remember to load the debris anims
Expand Down Expand Up @@ -507,43 +509,26 @@ void LabRenderer::useBackground(const SCP_string& mission_name) {
}
else {
Nebula_index = -1;
Mission_palette = std::max(generated_nebula_default_color(), 0);
Nebula_mission_switch = -1;
if (optional_string("+Nebula:")) {
char str[MAX_FILENAME_LEN];
int z;
stuff_string(str, F_NAME, MAX_FILENAME_LEN);

// parse the proper nebula type (full or not)
for (z = 0; z < NUM_NEBULAS; z++) {
if (flags[Mission::Mission_Flags::Fullneb]) {
if (!stricmp(str, Neb2_filenames[z])) {
Nebula_index = z;
break;
}
}
else {
if (!stricmp(str, Nebula_filenames[z])) {
Nebula_index = z;
break;
}
}
}

if (z == NUM_NEBULAS)
// look up the generated nebula pattern in the registry
Nebula_index = generated_nebula_pattern_lookup(str);
if (Nebula_index < 0)
WarningEx(LOCATION, "Unknown nebula %s!", str);

if (optional_string("+Color:")) {
stuff_string(str, F_NAME, MAX_FILENAME_LEN);
for (z = 0; z < NUM_NEBULA_COLORS; z++) {
if (!stricmp(str, Nebula_colors[z])) {
Mission_palette = z;
break;
}
}
int color_idx = generated_nebula_color_lookup(str);
if (color_idx < 0)
WarningEx(LOCATION, "Unknown nebula color %s!", str);
else
Mission_palette = color_idx;
}

if (z == NUM_NEBULA_COLORS)
WarningEx(LOCATION, "Unknown nebula color %s!", str);

if (optional_string("+Pitch:")) {
stuff_int(&Nebula_pitch);
}
Expand All @@ -564,6 +549,7 @@ void LabRenderer::useBackground(const SCP_string& mission_name) {
else {
Nebula_heading = 0;
}

}

nebula_init(Nebula_index, Nebula_pitch, Nebula_bank, Nebula_heading);
Expand All @@ -584,6 +570,12 @@ void LabRenderer::useBackground(const SCP_string& mission_name) {
stuff_string(envmap_name, F_NAME, MAX_FILENAME_LEN);
}

if (optional_string("$FS1 Nebula:")) {
bool on = false;
stuff_boolean(&on);
Nebula_mission_switch = on ? 1 : 0;
}

const int size = 512;
int gen_flags = (BMP_FLAG_RENDER_TARGET_STATIC | BMP_FLAG_CUBEMAP | BMP_FLAG_RENDER_TARGET_MIPMAP);

Expand Down
79 changes: 25 additions & 54 deletions code/mission/missionparse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ int Total_initially_docked;
mission The_mission;
char Mission_filename[80];

int Mission_palette; // index into Nebula_palette_filenames[] of palette file to use for mission
int Nebula_index; // index into Nebula_filenames[] of nebula to use in mission.
int Mission_palette; // index into Generated_nebula_colors of the generated nebula tint color
int Nebula_index; // index into Generated_nebula_patterns of the generated nebula to use in mission (-1 = none)
int Num_ai_behaviors = MAX_AI_BEHAVIORS;
int Num_cargo = 0;
int Num_arrival_names = MAX_ARRIVAL_NAMES;
Expand Down Expand Up @@ -222,31 +222,6 @@ static bool mission_has_layer_name(const mission* pm, const SCP_string& layerNam

//XSTR:OFF

const char *Nebula_filenames[NUM_NEBULAS] = {
"Nebula01",
"Nebula02",
"Nebula03"
};

const char *Neb2_filenames[NUM_NEBULAS] = {
"Nebfull01",
"Nebfull02",
"Nebfull03"
};

// Note: Nebula_colors[] and Nebula_palette_filenames are linked via index numbers
const char *Nebula_colors[NUM_NEBULA_COLORS] = {
"Red",
"Blue",
"Gold",
"Purple",
"Maroon",
"Green",
"Grey blue",
"Violet",
"Grey Green",
};

const char *Ai_behavior_names[MAX_AI_BEHAVIORS] = {
"Chase",
"Evade",
Expand Down Expand Up @@ -6337,7 +6312,6 @@ void parse_one_background(background_t *background)
void parse_bitmaps(mission *pm)
{
char str[MAX_FILENAME_LEN];
int z;

required_string("#Background bitmaps");

Expand Down Expand Up @@ -6403,38 +6377,26 @@ void parse_bitmaps(mission *pm)
} else {
if (optional_string("+Nebula:")) {
stuff_string(str, F_NAME, MAX_FILENAME_LEN);

// parse the proper nebula type (full or not)
for (z=0; z<NUM_NEBULAS; z++){
if(pm->flags[Mission::Mission_Flags::Fullneb]){
if (!stricmp(str, Neb2_filenames[z])) {
Nebula_index = z;
break;
}
} else {
if (!stricmp(str, Nebula_filenames[z])) {
Nebula_index = z;
break;
}
}
}

if (z == NUM_NEBULAS)
// look up the generated nebula pattern in the registry; an unknown name is kept so a
// save writes it back unchanged
Nebula_index = generated_nebula_pattern_lookup(str);
if (Nebula_index < 0) {
WarningEx(LOCATION, "Mission %s\nUnknown nebula %s!", pm->name.c_str(), str);
Nebula_unknown_pattern = str;
}

if (optional_string("+Color:")) {
stuff_string(str, F_NAME, MAX_FILENAME_LEN);
for (z=0; z<NUM_NEBULA_COLORS; z++){
if (!stricmp(str, Nebula_colors[z])) {
Mission_palette = z;
break;
}
int color_idx = generated_nebula_color_lookup(str);
if (color_idx < 0) {
WarningEx(LOCATION, "Mission %s\nUnknown nebula color %s!", pm->name.c_str(), str);
Nebula_unknown_color = str;
} else {
Mission_palette = color_idx;
}
}

if (z == NUM_NEBULA_COLORS)
WarningEx(LOCATION, "Mission %s\nUnknown nebula color %s!", pm->name.c_str(), str);

if (optional_string("+Pitch:")){
stuff_int(&Nebula_pitch);
} else {
Expand All @@ -6451,7 +6413,7 @@ void parse_bitmaps(mission *pm)
stuff_int(&Nebula_heading);
} else {
Nebula_heading = 0;
}
}
}

nebula_init(Nebula_index, Nebula_pitch, Nebula_bank, Nebula_heading);
Expand All @@ -6468,6 +6430,12 @@ void parse_bitmaps(mission *pm)
stuff_string(pm->envmap_name, F_NAME, MAX_FILENAME_LEN);
}

if (optional_string("$FS1 Nebula:")) {
bool on = false;
stuff_boolean(&on);
Nebula_mission_switch = on ? 1 : 0;
}

// bypass spurious stuff from e.g. FS1 missions
skip_to_start_of_string("#");
}
Expand Down Expand Up @@ -7501,7 +7469,10 @@ void mission_init(mission *pm, bool quick_init)
Nebula_bank = (int)((float)(Random::next() & 0x0fff) * 360.0f / 4096.0f);
Nebula_heading = (int)((float)(Random::next() & 0x0fff) * 360.0f / 4096.0f);
Nebula_index = -1;
Mission_palette = 1;
Mission_palette = std::max(generated_nebula_default_color(), 0);
Nebula_mission_switch = -1;
Nebula_unknown_pattern.clear();
Nebula_unknown_color.clear();
}

// Main parse routine for parsing a mission. The default parameter flags tells us which information
Expand Down
Loading
Loading