Skip to content
Merged
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ built world down with it, so the next one starts from an empty world.
| Section | Setting | Effect |
|---|---|---|
| `[graphics]` | `view_distance` | How far terrain is built and drawn [m], 1000 … 12000. The biggest single cost. |
| | `fov` | Vertical field of view of the cab camera [°], 60 … 120. Applies immediately, also while driving. |
| | `shadows` | Shadow maps of the sun. |
| | `bloom` | Glow around lamps and signals after dark. |
| | `shadow_quality` | Edge length of the sun's shadow map: `Low` 1024, `Medium` 2048, `High` 4096 texels. |
Expand Down
5 changes: 5 additions & 0 deletions crates/app/src/loading.rs
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,11 @@ pub(crate) fn load_sky(
},
Projection::Perspective(PerspectiveProjection {
far: 20_000.0,
fov: settings
.graphics
.fov
.clamp(crate::settings::FOV.0, crate::settings::FOV.1)
.to_radians(),
..default()
}),
Transform::default(),
Expand Down
18 changes: 16 additions & 2 deletions crates/app/src/menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ impl Entry {
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
enum Setting {
ViewDistance,
Fov,
TextureQuality,
Grass,
GrassQuality,
Expand Down Expand Up @@ -513,6 +514,7 @@ const SETTINGS: [(&str, &[Setting]); 4] = [
"set-graphics",
&[
Setting::ViewDistance,
Setting::Fov,
Setting::TextureQuality,
Setting::Grass,
Setting::GrassQuality,
Expand Down Expand Up @@ -543,6 +545,7 @@ impl Setting {
fn key(self) -> &'static str {
match self {
Setting::ViewDistance => "set-view-distance",
Setting::Fov => "set-fov",
Setting::TextureQuality => "set-texture-quality",
Setting::Grass => "set-grass",
Setting::GrassQuality => "set-grass-quality",
Expand All @@ -569,11 +572,12 @@ impl Setting {
}

fn control(self, graphics: &Graphics, audio: &Audio, gameplay: &Gameplay) -> Control {
use settings::{LOOK_SPEED, MAX_FPS, VIEW_DISTANCE, VOLUME};
use settings::{FOV, LOOK_SPEED, MAX_FPS, VIEW_DISTANCE, VOLUME};
match self {
Setting::ViewDistance => {
Control::Slider(fraction(graphics.view_distance, VIEW_DISTANCE))
}
Setting::Fov => Control::Slider(fraction(graphics.fov, FOV)),
Setting::Volume => Control::Slider(fraction(audio.master, VOLUME)),
Setting::MaxFps => Control::Slider(fraction(graphics.max_fps, MAX_FPS)),
Setting::LookSpeed => Control::Slider(fraction(gameplay.look_speed, LOOK_SPEED)),
Expand Down Expand Up @@ -609,6 +613,12 @@ impl Setting {
value = i18n::decimal(f64::from(graphics.view_distance), 0)
)
}
Setting::Fov => {
t!(
"set-degrees",
value = i18n::decimal(f64::from(graphics.fov), 0)
)
}
Setting::Volume => t!(
"set-percent",
value = i18n::decimal(f64::from(audio.master) * 100.0, 0)
Expand Down Expand Up @@ -746,11 +756,14 @@ fn change(
gameplay: &mut Gameplay,
support: &settings::UpscalingSupport,
) {
use settings::{LOOK_SPEED, MAX_FPS, VIEW_DISTANCE, VOLUME};
use settings::{FOV, LOOK_SPEED, MAX_FPS, VIEW_DISTANCE, VOLUME};
match setting {
Setting::ViewDistance => {
graphics.view_distance = step(graphics.view_distance, dir, VIEW_DISTANCE);
}
Setting::Fov => {
graphics.fov = step(graphics.fov, dir, FOV);
}
Setting::Shadows => graphics.shadows = !graphics.shadows,
Setting::Bloom => graphics.bloom = !graphics.bloom,
Setting::VolumetricClouds => graphics.volumetric_clouds = !graphics.volumetric_clouds,
Expand Down Expand Up @@ -4044,6 +4057,7 @@ mod tests {
(settings::VIEW_DISTANCE.0..=settings::VIEW_DISTANCE.1)
.contains(&graphics.view_distance)
);
assert!((settings::FOV.0..=settings::FOV.1).contains(&graphics.fov));
assert!((settings::VOLUME.0..=settings::VOLUME.1).contains(&audio.master));
assert!((settings::LOOK_SPEED.0..=settings::LOOK_SPEED.1).contains(&gameplay.look_speed));
// The language cycles through system + every shipped language and back.
Expand Down
19 changes: 17 additions & 2 deletions crates/app/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
//!
//! **Every setting applies the moment it is dialled.** Language, volume, HUD and look
//! sensitivity are read where they are used; window mode and vertical sync go onto the
//! window; view distance, shadows, bloom, anti-aliasing, upscaling and the shadow and
//! window; view distance, field of view, shadows, bloom, anti-aliasing, upscaling and the shadow and
//! mist quality reach into a running scene through `apply_scene`; the texture quality
//! generates the ground textures again into the handles the terrain already holds. A
//! setting that needs a restart is an excuse, and it would go stale the moment there is
Expand Down Expand Up @@ -46,6 +46,8 @@ const APP_ID: &str = "dev.vanlueck.connected-rails";

/// Terrain load and draw radius: smallest, largest, one step of the menu [m].
pub const VIEW_DISTANCE: (f32, f32, f32) = (1_000.0, 12_000.0, 500.0);
/// Vertical field of view of the cab camera: smallest, largest, one step [°].
pub const FOV: (f32, f32, f32) = (60.0, 120.0, 5.0);
/// Master volume: smallest, largest, one step (0 … 1).
pub const VOLUME: (f32, f32, f32) = (0.0, 1.0, 0.05);
/// Mouse look sensitivity as a factor on the built-in speed.
Expand All @@ -62,6 +64,8 @@ pub const MAX_FPS: (f32, f32, f32) = (30.0, 250.0, 10.0);
pub struct Graphics {
/// Terrain load and draw radius [m] — read by `setup` when the run starts.
pub view_distance: f32,
/// Vertical field of view of the cab camera [°].
pub fov: f32,
/// Windowed, borderless over the monitor, or exclusive fullscreen.
///
/// A settings file from before this was three steps carries `fullscreen = true`; the
Expand Down Expand Up @@ -115,6 +119,7 @@ impl Default for Graphics {
fn default() -> Self {
Self {
view_distance: 4_000.0,
fov: 90.0,
window: WindowStyle::Windowed,
vsync: true,
max_fps: MAX_FPS.1,
Expand Down Expand Up @@ -789,7 +794,7 @@ fn apply_window(graphics: Res<Graphics>, mut window: Query<&mut Window, With<Pri
}
}

/// View distance, upscaling, bloom and anti-aliasing into a scene that is already running. Every parameter is
/// View distance, field of view, upscaling, bloom and anti-aliasing into a scene that is already running. Every parameter is
/// optional because none of it exists while the menu is up — the world is built on
/// leaving it.
///
Expand All @@ -807,6 +812,7 @@ fn apply_scene(
grass: Option<ResMut<world_render::GrassRenderSettings>>,
grass_materials: Option<ResMut<Assets<world_render::GrassMaterial>>>,
cameras: Query<(Entity, Has<Bloom>), With<CabCamera>>,
mut projections: Query<&mut bevy::camera::Projection, With<CabCamera>>,
) {
// The sun's shadow map is a resource of Bevy's own, rebuilt from it every frame.
commands.insert_resource(DirectionalLightShadowMap {
Expand Down Expand Up @@ -846,6 +852,14 @@ fn apply_scene(
if let Some(mut streamer) = streamer {
streamer.set_load_radius(f64::from(graphics.view_distance));
}
// A hand-edited settings file may hold anything; the menu clamps on every step,
// so only the file needs it here.
let fov = graphics.fov.clamp(FOV.0, FOV.1).to_radians();
for mut projection in &mut projections {
if let bevy::camera::Projection::Perspective(perspective) = &mut *projection {
perspective.fov = fov;
}
}
for (camera, has_bloom) in &cameras {
match (graphics.bloom, has_bloom) {
(true, false) => {
Expand Down Expand Up @@ -936,6 +950,7 @@ mod tests {
fn defaults_lie_inside_the_ranges() {
let graphics = Graphics::default();
assert!((VIEW_DISTANCE.0..=VIEW_DISTANCE.1).contains(&graphics.view_distance));
assert!((FOV.0..=FOV.1).contains(&graphics.fov));
assert!((VOLUME.0..=VOLUME.1).contains(&Audio::default().master));
assert!((LOOK_SPEED.0..=LOOK_SPEED.1).contains(&Gameplay::default().look_speed));
}
Expand Down
3 changes: 3 additions & 0 deletions crates/i18n/locales/de/main.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -1549,6 +1549,8 @@ set-gameplay = Spiel
set-stored = Bleibt zwischen zwei Starts in der Einstellungsdatei des Benutzerkontos erhalten.
set-view-distance = Sichtweite
set-view-distance-hint = Wie weit Gelände gebaut und gezeichnet wird — der größte einzelne Posten.
set-fov = Sichtfeld
set-fov-hint = Vertikales Sichtfeld der Führerstandskamera, in Grad. Wirkt sofort, auch während der Fahrt.
set-shadows = Schatten
set-shadows-hint = Schattenkarten der Sonne.
set-bloom = Lichtschein
Expand Down Expand Up @@ -1619,6 +1621,7 @@ set-reset = Auf Standard zurücksetzen
set-reset-hint = Setzt jede Einstellung dieser Seite auf den Auslieferungszustand.
# Einheiten der Werte am rechten Rand einer Einstellungszeile.
set-metres = { $value } m
set-degrees = { $value }°
set-percent = { $value } %
set-factor = { $value } ×

Expand Down
3 changes: 3 additions & 0 deletions crates/i18n/locales/en/main.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -1546,6 +1546,8 @@ set-gameplay = Gameplay
set-stored = Kept between runs in the settings file of your user account.
set-view-distance = View distance
set-view-distance-hint = How far terrain is built and drawn — the biggest single cost.
set-fov = Field of view
set-fov-hint = Vertical field of view of the cab camera, in degrees. Applies right away, while driving too.
set-shadows = Shadows
set-shadows-hint = Shadow maps of the sun.
set-bloom = Bloom
Expand Down Expand Up @@ -1616,6 +1618,7 @@ set-reset = Reset to defaults
set-reset-hint = Puts every setting on this page back to how it shipped.
# Units of the values on the right of a settings row.
set-metres = { $value } m
set-degrees = { $value }°
set-percent = { $value } %
set-factor = { $value } ×

Expand Down