mirror of
https://github.com/vladtrc/iw4L
synced 2026-10-26 02:11:39 -04:00
Merge pull request #5 from chasmlol/lol/video-fov-slider
Add an FOV slider to video options
This commit is contained in:
@@ -219,6 +219,7 @@ fn serialize_settings(settings: &frame::GameSettings, binds: &KeyBinds) -> Strin
|
||||
),
|
||||
format!("fullscreen={}", settings.fullscreen),
|
||||
format!("vsync={}", settings.vsync),
|
||||
format!("fov={:.0}", settings.fov),
|
||||
format!("master_volume={:.3}", settings.master_volume),
|
||||
format!("sensitivity={:.3}", settings.sensitivity),
|
||||
format!("invert_mouse={}", settings.invert_mouse),
|
||||
@@ -269,6 +270,11 @@ fn parse_settings(source: &str, settings: &mut frame::GameSettings, binds: &mut
|
||||
settings.master_volume = value;
|
||||
}
|
||||
}
|
||||
"fov" => {
|
||||
if let Ok(value) = value.parse() {
|
||||
settings.fov = value;
|
||||
}
|
||||
}
|
||||
"sensitivity" => {
|
||||
if let Ok(value) = value.parse() {
|
||||
settings.sensitivity = value;
|
||||
|
||||
@@ -28,6 +28,7 @@ pub struct GameSettings {
|
||||
pub resolution: DisplayResolution,
|
||||
pub fullscreen: bool,
|
||||
pub vsync: bool,
|
||||
pub fov: f32,
|
||||
pub master_volume: f32,
|
||||
pub sensitivity: f32,
|
||||
pub invert_mouse: bool,
|
||||
@@ -42,6 +43,7 @@ impl Default for GameSettings {
|
||||
resolution: DisplayResolution::HD,
|
||||
fullscreen: false,
|
||||
vsync: true,
|
||||
fov: Self::FOV_DEFAULT,
|
||||
master_volume: 1.0,
|
||||
sensitivity: 5.0,
|
||||
invert_mouse: false,
|
||||
@@ -52,6 +54,10 @@ impl Default for GameSettings {
|
||||
}
|
||||
|
||||
impl GameSettings {
|
||||
pub const FOV_DEFAULT: f32 = 65.0;
|
||||
pub const FOV_MIN: f32 = 65.0;
|
||||
pub const FOV_MAX: f32 = 120.0;
|
||||
|
||||
pub fn touch(&mut self) {
|
||||
self.revision = self.revision.wrapping_add(1);
|
||||
}
|
||||
@@ -59,6 +65,11 @@ impl GameSettings {
|
||||
pub fn sanitize(&mut self) {
|
||||
self.resolution.width = self.resolution.width.clamp(640, 7680);
|
||||
self.resolution.height = self.resolution.height.clamp(480, 4320);
|
||||
self.fov = if self.fov.is_finite() {
|
||||
self.fov.clamp(Self::FOV_MIN, Self::FOV_MAX)
|
||||
} else {
|
||||
Self::FOV_DEFAULT
|
||||
};
|
||||
self.master_volume = self.master_volume.clamp(0.0, 1.0);
|
||||
self.sensitivity = self.sensitivity.clamp(0.1, 30.0);
|
||||
self.player_name = self.player_name.trim().chars().take(16).collect();
|
||||
|
||||
@@ -2,9 +2,8 @@ use assets::{PreparedWeapons, WeaponBodyFacts, WeaponKickFacts};
|
||||
use bevy::prelude::*;
|
||||
use frame::{LifeStarted, ViewSubject};
|
||||
use hud_iw4::{
|
||||
CG_FOV_DEFAULT, CG_FOV_MIN_DEFAULT, CG_FOV_SCALE_DEFAULT, CgCalcFovInputs,
|
||||
WeaponAdsOverlayFacts, cg_calc_fov_from_ads, cg_horizontal_to_vertical_fov_deg,
|
||||
cg_zoom_sensitivity,
|
||||
CG_FOV_MIN_DEFAULT, CG_FOV_SCALE_DEFAULT, CgCalcFovInputs, WeaponAdsOverlayFacts,
|
||||
cg_calc_fov_from_ads, cg_horizontal_to_vertical_fov_deg, cg_zoom_sensitivity,
|
||||
};
|
||||
use math_iw4::{add_lean_to_position, angle_vectors};
|
||||
use net::{
|
||||
@@ -240,6 +239,7 @@ pub fn sync_camera_from_presented(
|
||||
presented: Res<PresentedSnapshot>,
|
||||
local: Res<LocalPresentClient>,
|
||||
sim_cam: Res<SimCamera>,
|
||||
settings: Res<frame::GameSettings>,
|
||||
mut kick: ResMut<SessionViewKick>,
|
||||
mut hurt: ResMut<PendingViewHurt>,
|
||||
weapons: Option<Res<PreparedWeapons>>,
|
||||
@@ -319,6 +319,7 @@ pub fn sync_camera_from_presented(
|
||||
}
|
||||
apply_fpv_lens_fov(
|
||||
&mut lenses,
|
||||
settings.fov,
|
||||
ps.pm_type,
|
||||
ps.link_flags,
|
||||
ps.e_flags,
|
||||
@@ -439,6 +440,7 @@ pub fn sync_camera_from_presented(
|
||||
kick.last_weapon_pos_frac = ps.f_weapon_pos_frac;
|
||||
if let Some(horiz) = apply_fpv_lens_fov(
|
||||
&mut lenses,
|
||||
settings.fov,
|
||||
ps.pm_type,
|
||||
ps.link_flags,
|
||||
ps.e_flags,
|
||||
@@ -454,6 +456,7 @@ pub fn sync_camera_from_presented(
|
||||
|
||||
fn apply_fpv_lens_fov(
|
||||
lenses: &mut Query<&mut Projection, With<FpvLens>>,
|
||||
base_fov: f32,
|
||||
pm_type: i32,
|
||||
link_flags: u32,
|
||||
e_flags: u32,
|
||||
@@ -463,9 +466,7 @@ fn apply_fpv_lens_fov(
|
||||
b_position_to_ads: bool,
|
||||
actions: Option<&mut ClientActionInput>,
|
||||
) -> Option<f32> {
|
||||
let Some(facts) = facts.filter(|f| f.body_resolved) else {
|
||||
return None;
|
||||
};
|
||||
let facts = facts.filter(|f| f.body_resolved).unwrap_or_default();
|
||||
let overlay = WeaponAdsOverlayFacts {
|
||||
ads_zoom_in_frac: facts.ads_zoom_in_frac,
|
||||
ads_zoom_out_frac: facts.ads_zoom_out_frac,
|
||||
@@ -475,10 +476,10 @@ fn apply_fpv_lens_fov(
|
||||
let ads_target = if facts.ads_zoom_fov > 0.0 {
|
||||
facts.ads_zoom_fov
|
||||
} else {
|
||||
CG_FOV_DEFAULT
|
||||
base_fov
|
||||
};
|
||||
let inputs = CgCalcFovInputs {
|
||||
cg_fov: CG_FOV_DEFAULT,
|
||||
cg_fov: base_fov,
|
||||
pm_type,
|
||||
link_flags,
|
||||
e_flags,
|
||||
|
||||
@@ -143,6 +143,7 @@ pub enum SettingKey {
|
||||
Resolution,
|
||||
Fullscreen,
|
||||
Vsync,
|
||||
Fov,
|
||||
MasterVolume,
|
||||
Sensitivity,
|
||||
InvertMouse,
|
||||
|
||||
@@ -167,7 +167,7 @@ pub(crate) fn options_widget_is_active(state: &OptionsState, id: &str) -> bool {
|
||||
OptionsDepth::SectionRows => match state.tab {
|
||||
OptionsTab::Video => matches!(
|
||||
id,
|
||||
"options/resolution" | "options/fullscreen" | "options/vsync"
|
||||
"options/resolution" | "options/fullscreen" | "options/vsync" | "options/fov"
|
||||
),
|
||||
OptionsTab::Audio => id == "options/volume",
|
||||
OptionsTab::Controls => OptionsControlGroup::from_widget_id(id).is_some(),
|
||||
@@ -273,6 +273,7 @@ pub(crate) fn drive_options_navigation(
|
||||
focus.widget.as_deref(),
|
||||
Some(
|
||||
"options/volume"
|
||||
| "options/fov"
|
||||
| "options/sensitivity"
|
||||
| "options/fullscreen"
|
||||
| "options/vsync"
|
||||
@@ -445,6 +446,12 @@ pub(crate) fn apply_option_intents(
|
||||
(SettingKey::Vsync, SettingValue::Bool(value)) => {
|
||||
replace(&mut settings.vsync, *value)
|
||||
}
|
||||
(SettingKey::Fov, SettingValue::Float(value)) if value.is_finite() => {
|
||||
let value = value
|
||||
.clamp(frame::GameSettings::FOV_MIN, frame::GameSettings::FOV_MAX)
|
||||
.round();
|
||||
replace(&mut settings.fov, value)
|
||||
}
|
||||
(SettingKey::MasterVolume, SettingValue::Float(value)) => {
|
||||
let value = value.clamp(0.0, 1.0);
|
||||
replace(&mut settings.master_volume, value)
|
||||
|
||||
@@ -1343,6 +1343,18 @@ pub fn options(host: Host<'_>) -> Screen {
|
||||
None,
|
||||
"Synchronize presentation to the display refresh.",
|
||||
),
|
||||
slider(
|
||||
"options/fov",
|
||||
238.0,
|
||||
122.0,
|
||||
"Field of View",
|
||||
settings.fov,
|
||||
frame::GameSettings::FOV_MIN,
|
||||
frame::GameSettings::FOV_MAX,
|
||||
1.0,
|
||||
crate::SettingKey::Fov,
|
||||
"Show more of your surroundings. Default: 65.",
|
||||
),
|
||||
]);
|
||||
}
|
||||
OptionsTab::Audio => {
|
||||
|
||||
Reference in New Issue
Block a user