forked from StrafesNET/strafe-project
implement settings
This commit is contained in:
parent
3b7a1d5dff
commit
7f7b0d92e6
@ -57,7 +57,17 @@ pub struct Ratio64{
|
|||||||
den:std::num::NonZeroU64,
|
den:std::num::NonZeroU64,
|
||||||
}
|
}
|
||||||
impl Ratio64{
|
impl Ratio64{
|
||||||
|
pub const ZERO:Self=Ratio64{num:0,den:unsafe{std::num::NonZeroU64::new_unchecked(1)}};
|
||||||
pub const ONE:Self=Ratio64{num:1,den:unsafe{std::num::NonZeroU64::new_unchecked(1)}};
|
pub const ONE:Self=Ratio64{num:1,den:unsafe{std::num::NonZeroU64::new_unchecked(1)}};
|
||||||
|
pub fn new(num:i64,den:u64)->Option<Ratio64>{
|
||||||
|
match std::num::NonZeroU64::new(den){
|
||||||
|
Some(den)=>{
|
||||||
|
//TODO: gcd
|
||||||
|
Some(Self{num,den})
|
||||||
|
},
|
||||||
|
None=>None,
|
||||||
|
}
|
||||||
|
}
|
||||||
pub fn mul_int(self,rhs:i64)->i64{
|
pub fn mul_int(self,rhs:i64)->i64{
|
||||||
rhs*self.num/self.den.get() as i64
|
rhs*self.num/self.den.get() as i64
|
||||||
}
|
}
|
||||||
@ -65,6 +75,68 @@ impl Ratio64{
|
|||||||
rhs*self.den.get() as i64/self.num
|
rhs*self.den.get() as i64/self.num
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//from num_traits crate
|
||||||
|
#[inline]
|
||||||
|
fn integer_decode_f64(f: f64) -> (u64, i16, i8) {
|
||||||
|
let bits: u64 = f.to_bits();
|
||||||
|
let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 };
|
||||||
|
let mut exponent: i16 = ((bits >> 52) & 0x7ff) as i16;
|
||||||
|
let mantissa = if exponent == 0 {
|
||||||
|
(bits & 0xfffffffffffff) << 1
|
||||||
|
} else {
|
||||||
|
(bits & 0xfffffffffffff) | 0x10000000000000
|
||||||
|
};
|
||||||
|
// Exponent bias + mantissa shift
|
||||||
|
exponent -= 1023 + 52;
|
||||||
|
(mantissa, exponent, sign)
|
||||||
|
}
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum Ratio64TryFromFloat64Error{
|
||||||
|
Nan,
|
||||||
|
Infinite,
|
||||||
|
Subnormal,
|
||||||
|
HighlyNegativeExponent(i16),
|
||||||
|
HighlyPositiveExponent(i16),
|
||||||
|
}
|
||||||
|
impl TryFrom<f64> for Ratio64{
|
||||||
|
type Error=Ratio64TryFromFloat64Error;
|
||||||
|
fn try_from(value:f64)->Result<Self,Self::Error>{
|
||||||
|
match value.classify(){
|
||||||
|
std::num::FpCategory::Nan=>Err(Self::Error::Nan),
|
||||||
|
std::num::FpCategory::Infinite=>Err(Self::Error::Infinite),
|
||||||
|
std::num::FpCategory::Zero=>Ok(Self::ZERO),
|
||||||
|
std::num::FpCategory::Subnormal=>Err(Self::Error::Subnormal),
|
||||||
|
std::num::FpCategory::Normal=>{
|
||||||
|
let (m,e,s)=integer_decode_f64(value);
|
||||||
|
if e< -127{
|
||||||
|
//bye bye
|
||||||
|
Err(Self::Error::HighlyNegativeExponent(e))
|
||||||
|
}else if e< -63{
|
||||||
|
//TODO
|
||||||
|
Err(Self::Error::HighlyNegativeExponent(e))
|
||||||
|
}else if e<0{
|
||||||
|
Ok(Ratio64::new((m as i64)*(s as i64),1<<-e).unwrap())
|
||||||
|
}else if e<62-52{
|
||||||
|
Ok(Ratio64::new((m as i64)*(s as i64)*(1<<e),1).unwrap())
|
||||||
|
}else{
|
||||||
|
Err(Self::Error::HighlyPositiveExponent(e))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl std::ops::Mul<Ratio64> for Ratio64{
|
||||||
|
type Output=Ratio64;
|
||||||
|
#[inline]
|
||||||
|
fn mul(self,rhs:Ratio64)->Self::Output{
|
||||||
|
let (num,den)=(self.num*rhs.num,self.den.get()*rhs.den.get());
|
||||||
|
//TODO: gcd
|
||||||
|
Self{
|
||||||
|
num,
|
||||||
|
den:unsafe{std::num::NonZeroU64::new_unchecked(den)},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
impl std::ops::Mul<i64> for Ratio64{
|
impl std::ops::Mul<i64> for Ratio64{
|
||||||
type Output=Ratio64;
|
type Output=Ratio64;
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -92,6 +164,9 @@ pub struct Ratio64Vec2{
|
|||||||
}
|
}
|
||||||
impl Ratio64Vec2{
|
impl Ratio64Vec2{
|
||||||
pub const ONE:Self=Self{x:Ratio64::ONE,y:Ratio64::ONE};
|
pub const ONE:Self=Self{x:Ratio64::ONE,y:Ratio64::ONE};
|
||||||
|
pub fn new(x:Ratio64,y:Ratio64)->Self{
|
||||||
|
Self{x,y}
|
||||||
|
}
|
||||||
pub fn mul_int(self,rhs:glam::I64Vec2)->glam::I64Vec2{
|
pub fn mul_int(self,rhs:glam::I64Vec2)->glam::I64Vec2{
|
||||||
glam::i64vec2(
|
glam::i64vec2(
|
||||||
self.x.mul_int(rhs.x),
|
self.x.mul_int(rhs.x),
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use crate::integer::{Ratio64,Ratio64Vec2};
|
||||||
struct Ratio{
|
struct Ratio{
|
||||||
ratio:f64,
|
ratio:f64,
|
||||||
}
|
}
|
||||||
@ -7,23 +8,25 @@ enum DerivedFov{
|
|||||||
}
|
}
|
||||||
enum Fov{
|
enum Fov{
|
||||||
Exactly{x:f64,y:f64},
|
Exactly{x:f64,y:f64},
|
||||||
DeriveX{x:DerivedFov,y:f64},
|
SpecifyXDeriveY{x:f64,y:DerivedFov},
|
||||||
DeriveY{x:f64,y:DerivedFov},
|
SpecifyYDeriveX{x:DerivedFov,y:f64},
|
||||||
}
|
}
|
||||||
impl Default for Fov{
|
impl Default for Fov{
|
||||||
fn default()->Self{
|
fn default()->Self{
|
||||||
Fov::DeriveX{x:DerivedFov::FromScreenAspect,y:1.0}
|
Fov::SpecifyYDeriveX{x:DerivedFov::FromScreenAspect,y:1.0}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
enum DerivedSensitivity{
|
||||||
|
FromRatio(Ratio64),
|
||||||
|
}
|
||||||
enum Sensitivity{
|
enum Sensitivity{
|
||||||
Exactly{x:f64,y:f64},
|
Exactly{x:Ratio64,y:Ratio64},
|
||||||
DeriveX{x:Ratio,y:f64},
|
SpecifyXDeriveY{x:Ratio64,y:DerivedSensitivity},
|
||||||
DeriveY{x:f64,y:Ratio},
|
SpecifyYDeriveX{x:DerivedSensitivity,y:Ratio64},
|
||||||
}
|
}
|
||||||
impl Default for Sensitivity{
|
impl Default for Sensitivity{
|
||||||
fn default()->Self{
|
fn default()->Self{
|
||||||
Sensitivity::DeriveY{x:0.001,y:Ratio{ratio:1.0}}
|
Sensitivity::SpecifyXDeriveY{x:Ratio64::ONE/1000,y:DerivedSensitivity::FromRatio(Ratio64::ONE)}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,21 +39,25 @@ impl UserSettings{
|
|||||||
pub fn calculate_fov(&self,zoom:f64,screen_size:&glam::UVec2)->glam::DVec2{
|
pub fn calculate_fov(&self,zoom:f64,screen_size:&glam::UVec2)->glam::DVec2{
|
||||||
zoom*match &self.fov{
|
zoom*match &self.fov{
|
||||||
&Fov::Exactly{x,y}=>glam::dvec2(x,y),
|
&Fov::Exactly{x,y}=>glam::dvec2(x,y),
|
||||||
Fov::DeriveX{x,y}=>match x{
|
Fov::SpecifyXDeriveY{x,y}=>match y{
|
||||||
DerivedFov::FromScreenAspect=>glam::dvec2(y*(screen_size.x as f64/screen_size.y as f64),*y),
|
|
||||||
DerivedFov::FromAspect(ratio)=>glam::dvec2(y*ratio.ratio,*y),
|
|
||||||
},
|
|
||||||
Fov::DeriveY{x,y}=>match y{
|
|
||||||
DerivedFov::FromScreenAspect=>glam::dvec2(*x,x*(screen_size.y as f64/screen_size.x as f64)),
|
DerivedFov::FromScreenAspect=>glam::dvec2(*x,x*(screen_size.y as f64/screen_size.x as f64)),
|
||||||
DerivedFov::FromAspect(ratio)=>glam::dvec2(*x,x*ratio.ratio),
|
DerivedFov::FromAspect(ratio)=>glam::dvec2(*x,x*ratio.ratio),
|
||||||
},
|
},
|
||||||
|
Fov::SpecifyYDeriveX{x,y}=>match x{
|
||||||
|
DerivedFov::FromScreenAspect=>glam::dvec2(y*(screen_size.x as f64/screen_size.y as f64),*y),
|
||||||
|
DerivedFov::FromAspect(ratio)=>glam::dvec2(y*ratio.ratio,*y),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn calculate_sensitivity(&self)->glam::DVec2{
|
pub fn calculate_sensitivity(&self)->Ratio64Vec2{
|
||||||
match &self.sensitivity{
|
match &self.sensitivity{
|
||||||
&Sensitivity::Exactly{x,y}=>glam::dvec2(x,y),
|
&Sensitivity::Exactly{x,y}=>Ratio64Vec2::new(x,y),
|
||||||
Sensitivity::DeriveX{x,y}=>glam::dvec2(y*x.ratio,*y),
|
Sensitivity::SpecifyXDeriveY{x,y}=>match y{
|
||||||
Sensitivity::DeriveY{x,y}=>glam::dvec2(*x,x*y.ratio),
|
&DerivedSensitivity::FromRatio(ratio)=>Ratio64Vec2::new(*x,*x*ratio),
|
||||||
|
}
|
||||||
|
Sensitivity::SpecifyYDeriveX{x,y}=>match x{
|
||||||
|
&DerivedSensitivity::FromRatio(ratio)=>Ratio64Vec2::new(*y*ratio,*y),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -71,7 +78,7 @@ pub fn read_user_settings()->UserSettings{
|
|||||||
x:fov_x,
|
x:fov_x,
|
||||||
y:fov_y
|
y:fov_y
|
||||||
},
|
},
|
||||||
(Ok(Some(fov_x)),Ok(None))=>Fov::DeriveY{
|
(Ok(Some(fov_x)),Ok(None))=>Fov::SpecifyXDeriveY{
|
||||||
x:fov_x,
|
x:fov_x,
|
||||||
y:if let Ok(Some(fov_y_from_x_ratio))=cfg.getfloat("camera","fov_y_from_x_ratio"){
|
y:if let Ok(Some(fov_y_from_x_ratio))=cfg.getfloat("camera","fov_y_from_x_ratio"){
|
||||||
DerivedFov::FromAspect(Ratio{ratio:fov_y_from_x_ratio})
|
DerivedFov::FromAspect(Ratio{ratio:fov_y_from_x_ratio})
|
||||||
@ -79,7 +86,7 @@ pub fn read_user_settings()->UserSettings{
|
|||||||
DerivedFov::FromScreenAspect
|
DerivedFov::FromScreenAspect
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
(Ok(None),Ok(Some(fov_y)))=>Fov::DeriveX{
|
(Ok(None),Ok(Some(fov_y)))=>Fov::SpecifyYDeriveX{
|
||||||
x:if let Ok(Some(fov_x_from_y_ratio))=cfg.getfloat("camera","fov_x_from_y_ratio"){
|
x:if let Ok(Some(fov_x_from_y_ratio))=cfg.getfloat("camera","fov_x_from_y_ratio"){
|
||||||
DerivedFov::FromAspect(Ratio{ratio:fov_x_from_y_ratio})
|
DerivedFov::FromAspect(Ratio{ratio:fov_x_from_y_ratio})
|
||||||
}else{
|
}else{
|
||||||
@ -94,20 +101,24 @@ pub fn read_user_settings()->UserSettings{
|
|||||||
let (cfg_sensitivity_x,cfg_sensitivity_y)=(cfg.getfloat("camera","sensitivity_x"),cfg.getfloat("camera","sensitivity_y"));
|
let (cfg_sensitivity_x,cfg_sensitivity_y)=(cfg.getfloat("camera","sensitivity_x"),cfg.getfloat("camera","sensitivity_y"));
|
||||||
let sensitivity=match(cfg_sensitivity_x,cfg_sensitivity_y){
|
let sensitivity=match(cfg_sensitivity_x,cfg_sensitivity_y){
|
||||||
(Ok(Some(sensitivity_x)),Ok(Some(sensitivity_y)))=>Sensitivity::Exactly {
|
(Ok(Some(sensitivity_x)),Ok(Some(sensitivity_y)))=>Sensitivity::Exactly {
|
||||||
x:sensitivity_x,
|
x:Ratio64::try_from(sensitivity_x).unwrap(),
|
||||||
y:sensitivity_y
|
y:Ratio64::try_from(sensitivity_y).unwrap(),
|
||||||
},
|
},
|
||||||
(Ok(Some(sensitivity_x)),Ok(None))=>Sensitivity::DeriveY{
|
(Ok(Some(sensitivity_x)),Ok(None))=>Sensitivity::SpecifyXDeriveY{
|
||||||
x:sensitivity_x,
|
x:Ratio64::try_from(sensitivity_x).unwrap(),
|
||||||
y:Ratio{
|
y:if let Ok(Some(sensitivity_y_from_x_ratio))=cfg.getfloat("camera","sensitivity_y_from_x_ratio"){
|
||||||
ratio:if let Ok(Some(sensitivity_y_from_x_ratio))=cfg.getfloat("camera","sensitivity_y_from_x_ratio"){sensitivity_y_from_x_ratio}else{1.0}
|
DerivedSensitivity::FromRatio(Ratio64::try_from(sensitivity_y_from_x_ratio).unwrap())
|
||||||
}
|
}else{
|
||||||
|
DerivedSensitivity::FromRatio(Ratio64::ONE)
|
||||||
},
|
},
|
||||||
(Ok(None),Ok(Some(sensitivity_y)))=>Sensitivity::DeriveX{
|
|
||||||
x:Ratio{
|
|
||||||
ratio:if let Ok(Some(sensitivity_x_from_y_ratio))=cfg.getfloat("camera","sensitivity_x_from_y_ratio"){sensitivity_x_from_y_ratio}else{1.0}
|
|
||||||
},
|
},
|
||||||
y:sensitivity_y,
|
(Ok(None),Ok(Some(sensitivity_y)))=>Sensitivity::SpecifyYDeriveX{
|
||||||
|
x:if let Ok(Some(sensitivity_x_from_y_ratio))=cfg.getfloat("camera","sensitivity_x_from_y_ratio"){
|
||||||
|
DerivedSensitivity::FromRatio(Ratio64::try_from(sensitivity_x_from_y_ratio).unwrap())
|
||||||
|
}else{
|
||||||
|
DerivedSensitivity::FromRatio(Ratio64::ONE)
|
||||||
|
},
|
||||||
|
y:Ratio64::try_from(sensitivity_y).unwrap(),
|
||||||
},
|
},
|
||||||
_=>{
|
_=>{
|
||||||
Sensitivity::default()
|
Sensitivity::default()
|
||||||
|
Loading…
Reference in New Issue
Block a user