Progress Update

This commit is contained in:
ResetXPDR 2024-02-18 09:06:03 +11:00
parent 6806e32d8c
commit 7c55be1713
11 changed files with 185 additions and 540 deletions

1
.gitignore vendored
View File

@ -371,3 +371,4 @@ MigrationBackup/
FodyWeavers.xsd
/DynamicLOD/CopyToMSFS.ps1
/DynamicLOD_ResetEdition/DevNotes.txt
/MSFS2020_AutoFPS/Dev Notes.txt

View File

@ -32,14 +32,14 @@ namespace MSFS2020_AutoFPS
return;
}
if (Process.GetProcessesByName("DynamicLOD_ResetEdition").Length > 0)
if (Process.GetProcessesByName("DynamicLOD_ResetEdition").Length > 1)
{
MessageBox.Show("DynamicLOD_ResetEdition is already running!", "Critical Error", MessageBoxButton.OK, MessageBoxImage.Error);
Application.Current.Shutdown();
return;
}
if (Process.GetProcessesByName("DynamicLOD").Length > 0)
if (Process.GetProcessesByName("DynamicLOD").Length > 1)
{
MessageBox.Show("A pre-ResetEdition version of AutoLOD is already running!", "Critical Error", MessageBoxButton.OK, MessageBoxImage.Error);
Application.Current.Shutdown();

View File

@ -20,12 +20,8 @@ namespace MSFS2020_AutoFPS
private int altAboveGnd = 0;
private int groundSpeed = 0;
private float tlod = 0;
private float tlod_dec = 0;
private float olod = 0;
private float olod_dec = 0;
private int cloudQ = 0;
private int cloudQ_VR = 0;
public bool FirstStart { get; set; } = true;
private int fpsModeTicks = 0;
private int fpsModeDelayTicks = 0;
@ -40,7 +36,6 @@ namespace MSFS2020_AutoFPS
SimConnect.SubscribeSimVar("SIM ON GROUND", "Bool");
SimConnect.SubscribeSimVar("GROUND VELOCITY", "knots");
tlod = Model.MemoryAccess.GetTLOD_PC();
olod = Model.MemoryAccess.GetOLOD_PC();
cloudQ = Model.MemoryAccess.GetCloudQ_PC();
cloudQ_VR = Model.MemoryAccess.GetCloudQ_VR();
if (cloudQ > Model.DefaultCloudQ) Model.DefaultCloudQ = cloudQ;
@ -76,7 +71,6 @@ namespace MSFS2020_AutoFPS
groundSpeed = (int)SimConnect.ReadSimVar("GROUND VELOCITY", "knots");
tlod = Model.MemoryAccess.GetTLOD_PC();
olod = Model.MemoryAccess.GetOLOD_PC();
cloudQ = Model.MemoryAccess.GetCloudQ_PC();
cloudQ_VR = Model.MemoryAccess.GetCloudQ_VR();
}
@ -86,200 +80,76 @@ namespace MSFS2020_AutoFPS
{
UpdateVariables();
int FPSTolerance;
bool GroundTLODChanges;
bool DecCloudQ;
float MinTLOD;
float MaxTLOD;
float newTLOD;
float deltaFPS = GetAverageFPS() - Model.TargetFPS;
if (Math.Abs(deltaFPS) >= Model.TargetFPS * Model.FPSTolerance / 100)
float CloudRecoveryTLOD;
if (Model.UseExpertOptions)
{
newTLOD = tlod + Math.Sign(deltaFPS) * Model.LodStepMaxInc * (Math.Abs(deltaFPS) >= Model.TargetFPS * 2 * Model.FPSTolerance / 100 && (groundSpeed < 1 || !Model.OnGround) ? 2 : 1) * (altAboveGnd < 1000 && !Model.OnGround ? (float)altAboveGnd / 1000 : 1);
newTLOD = Math.Min(Model.MaxTLOD, Math.Max(Model.MinTLOD, newTLOD));
FPSTolerance = Model.FPSTolerance;
GroundTLODChanges = Model.GroundTLODChanges;
MinTLOD = Model.MinTLOD;
MaxTLOD = Model.MaxTLOD;
DecCloudQ = Model.DecCloudQ;
CloudRecoveryTLOD = Model.CloudRecoveryTLOD;
}
else
{
FPSTolerance = 5;
GroundTLODChanges = true;
if (Model.MemoryAccess.IsVrModeActive())
{
MinTLOD = Math.Max(Model.DefaultTLOD_VR * 0.5f, 10);
MaxTLOD = Model.DefaultTLOD_VR * 2.0f;
}
else
{
MinTLOD = Math.Max(Model.DefaultTLOD * 0.5f, 10);
MaxTLOD = Model.DefaultTLOD * 2.0f;
}
DecCloudQ = true;
CloudRecoveryTLOD = Model.DefaultTLOD - 1;
}
float deltaFPS = GetAverageFPS() - Model.TargetFPS;
if (Math.Abs(deltaFPS) >= Model.TargetFPS * FPSTolerance / 100)
{
newTLOD = tlod + (GroundTLODChanges && Model.OnGround ? Math.Sign(deltaFPS) * FPSTolerance * (Math.Abs(deltaFPS) >= Model.TargetFPS * 2 * FPSTolerance / 100 && (groundSpeed < 1 || !Model.OnGround) ? 2 : 1) * (altAboveGnd < 1000 && !Model.OnGround ? (float)altAboveGnd / 1000 : 1) : 0);
newTLOD = (float)Math.Round(Math.Min(MaxTLOD, Math.Max(MinTLOD, newTLOD)));
if (Math.Abs(tlod - newTLOD) >= 1 && (!Model.OnGround || groundSpeed < 1))
{
Model.MemoryAccess.SetTLOD(newTLOD);
Model.tlod_step = true;
if (DecCloudQ && newTLOD == MinTLOD)
{
if (Model.MemoryAccess.IsVrModeActive() && Model.DefaultCloudQ_VR >= 1)
{
Model.MemoryAccess.SetCloudQ_VR(Model.DefaultCloudQ_VR - 1);
Model.DecCloudQActive = true;
}
if (!Model.MemoryAccess.IsVrModeActive() && Model.DefaultCloudQ >= 1)
{
Model.MemoryAccess.SetCloudQ(Model.DefaultCloudQ - 1);
Model.DecCloudQActive = true;
}
}
if (DecCloudQ && Model.DecCloudQActive && newTLOD >= CloudRecoveryTLOD)
{
if (Model.MemoryAccess.IsVrModeActive()) Model.MemoryAccess.SetCloudQ_VR(Model.DefaultCloudQ_VR);
else Model.MemoryAccess.SetCloudQ(Model.DefaultCloudQ);
Model.DecCloudQActive = false;
}
}
else Model.tlod_step = false;
if (Model.DecCloudQ && newTLOD == Model.MinTLOD)
{
if (Model.MemoryAccess.IsVrModeActive() && Model.DefaultCloudQ_VR >= 1)
{
Model.MemoryAccess.SetCloudQ_VR(Model.DefaultCloudQ_VR - 1);
Model.DecCloudQActive = true;
}
if (!Model.MemoryAccess.IsVrModeActive() && Model.DefaultCloudQ >= 1)
{
Model.MemoryAccess.SetCloudQ(Model.DefaultCloudQ - 1);
Model.DecCloudQActive = true;
}
}
if (Model.DecCloudQ && Model.DecCloudQActive && newTLOD >= Model.CloudRecoveryTLOD)
{
if (Model.MemoryAccess.IsVrModeActive()) Model.MemoryAccess.SetCloudQ_VR(Model.DefaultCloudQ_VR);
else Model.MemoryAccess.SetCloudQ(Model.DefaultCloudQ);
Model.DecCloudQActive = false;
}
}
else
{
Model.tlod_step = false;
Model.olod_step = false;
}
return;
if (FirstStart)
{
fpsModeTicks++;
if (fpsModeTicks > 2)
FindPairs();
Model.ForceEvaluation = false;
return;
}
if (Model.ForceEvaluation) FindPairs();
if (Model.UseTargetFPS)
{
if (GetAverageFPS() < Model.TargetFPS)
{
if (!Model.fpsMode)
{
if (fpsModeDelayTicks >= Model.ConstraintDelayTicks)
{
Logger.Log(LogLevel.Information, "LODController:RunTick", $"FPS Constraint active");
Model.fpsMode = true;
if (Model.DecCloudQ && Model.DefaultCloudQ >= 1)
{
Model.MemoryAccess.SetCloudQ(Model.DefaultCloudQ - 1);
}
if (Model.DecCloudQ && Model.DefaultCloudQ_VR >= 1)
{
Model.MemoryAccess.SetCloudQ_VR(Model.DefaultCloudQ_VR - 1);
}
tlod_dec = Model.DecreaseTLOD;
olod_dec = Model.DecreaseOLOD;
fpsModeDelayTicks = 0;
}
else fpsModeDelayTicks++; }
}
else if (GetAverageFPS() > Model.TargetFPS + (Model.DecCloudQ ? Model.CloudRecoveryTLOD : 0) && Model.fpsMode)
{
fpsModeTicks++;
if (fpsModeTicks > Model.ConstraintTicks || Model.ForceEvaluation)
ResetFPSMode();
}
else fpsModeDelayTicks = 0;
}
else if (!Model.UseTargetFPS && Model.fpsMode)
ResetFPSMode();
float evalResult = EvaluateLodPairByHeight(ref Model.CurrentPairTLOD, Model.PairsTLOD[Model.SelectedProfile]);
if (VerticalAverage() > 0 && Model.CurrentPairTLOD + 1 < Model.PairsTLOD[Model.SelectedProfile].Count)
Model.AltLead = Math.Abs(Model.PairsTLOD[Model.SelectedProfile][Model.CurrentPairTLOD + 1].Item2 - Model.PairsTLOD[Model.SelectedProfile][Model.CurrentPairTLOD].Item2) / Model.LodStepMaxInc * VSAverage();
else if (VerticalAverage() < 0 && Model.CurrentPairTLOD - 1 >= 0)
Model.AltLead = Math.Abs(Model.PairsTLOD[Model.SelectedProfile][Model.CurrentPairTLOD].Item2 - Model.PairsTLOD[Model.SelectedProfile][Model.CurrentPairTLOD - 1].Item2) / Model.LodStepMaxDec * VSAverage();
else Model.AltLead = 0;
float newlod = EvaluateLodValue(Model.PairsTLOD[Model.SelectedProfile], Model.CurrentPairTLOD, tlod_dec, true);
if (tlod != newlod)
{
if (evalResult > 0) Logger.Log(LogLevel.Information, "LODController:RunTick", $"Setting TLOD {newlod}" + (Model.LodStepMax ? " in steps" : ""));
if (!Model.ForceEvaluation)
{
Model.tlod_step = true;
if (tlod > newlod)
{
if (tlod - Model.LodStepMaxDec > newlod) newlod = tlod - Model.LodStepMaxDec;
else Model.tlod_step = false;
}
else
{
if (tlod + Model.LodStepMaxInc < newlod) newlod = tlod + Model.LodStepMaxInc;
else Model.tlod_step = false;
}
}
Model.MemoryAccess.SetTLOD(newlod);
}
else Model.tlod_step = false;
evalResult = EvaluateLodPairByHeight(ref Model.CurrentPairOLOD, Model.PairsOLOD[Model.SelectedProfile]);
newlod = EvaluateLodValue(Model.PairsOLOD[Model.SelectedProfile], Model.CurrentPairOLOD, olod_dec, false);
if (olod != newlod)
{
if (evalResult > 0) Logger.Log(LogLevel.Information, "LODController:RunTick", $"Setting OLOD {newlod}" + (Model.LodStepMax ? " in steps" : ""));
if (!Model.ForceEvaluation)
{
Model.olod_step = true;
if (olod > newlod)
{
if (olod - Model.LodStepMaxDec > newlod) newlod = olod - Model.LodStepMaxDec;
else Model.olod_step = false;
}
else
{
if (olod + Model.LodStepMaxInc < newlod) newlod = olod + Model.LodStepMaxInc;
else Model.olod_step = false;
}
}
Model.MemoryAccess.SetOLOD(newlod);
}
else Model.olod_step = false;
Model.ForceEvaluation = false;
}
private float EvaluateLodValue(List<(float, float)> pairs, int currentPair, float decrement, bool tlod)
{
if (Model.fpsMode)
return Math.Max(pairs[currentPair].Item2 - decrement, Math.Max((tlod ? Model.MinTLOD : Model.MaxTLOD), Model.SimMinLOD));
else
return Math.Max(pairs[currentPair].Item2, Model.SimMinLOD);
}
private void ResetFPSMode(bool logEntry = true)
{
if (logEntry) Logger.Log(LogLevel.Information, "LODController:RunTick", $"FPS Constraint lifted");
Model.fpsMode = false;
fpsModeTicks = 0;
fpsModeDelayTicks = 0;
tlod_dec = 0;
olod_dec = 0;
if (Model.DecCloudQ || Model.ForceEvaluation)
{
Model.MemoryAccess.SetCloudQ(Model.DefaultCloudQ);
Model.MemoryAccess.SetCloudQ_VR(Model.DefaultCloudQ_VR);
}
}
private float EvaluateLodPairByHeight(ref int index, List<(float, float)> lodPairs)
{
float result = -1.0f;
Logger.Log(LogLevel.Verbose, "LODController:EvaluateLodByHeight", $"VerticalAverage {VerticalAverage()}");
if ((VerticalAverage() > 0 || Model.ForceEvaluation) && index + 1 < lodPairs.Count && altAboveGnd + Math.Abs(lodPairs[index + 1].Item2 - lodPairs[index].Item2) / Model.LodStepMaxInc * VSAverage() > lodPairs[index + 1].Item1)
{
index++;
Logger.Log(LogLevel.Information, "LODController:EvaluateLodByHeight", $"Higher Pair found (altAboveGnd: {altAboveGnd} | index: {index} | lod: {lodPairs[index].Item2})");
return lodPairs[index].Item2;
}
else if ((VerticalAverage() < 0 || Model.ForceEvaluation) && index - 1 >= 0 && altAboveGnd + Math.Abs(lodPairs[index].Item2 - lodPairs[index - 1].Item2) / Model.LodStepMaxDec * VSAverage() < lodPairs[index].Item1)
{
index--;
Logger.Log(LogLevel.Information, "LODController:EvaluateLodByHeight", $"Lower Pair found (altAboveGnd: {altAboveGnd} | index: {index} | lod: {lodPairs[index].Item2})");
return lodPairs[index].Item2;
}
else if (VerticalAverage() == 0 && index + 1 < lodPairs.Count && altAboveGnd * 0.95 > lodPairs[index + 1].Item1)
{
index++;
Logger.Log(LogLevel.Information, "LODController:EvaluateLodByHeight", $"Higher Pair found (altAboveGnd: {altAboveGnd} | index: {index} | lod: {lodPairs[index].Item2})");
return lodPairs[index].Item2;
}
else if (VerticalAverage() == 0 && altAboveGnd * 1.05 < lodPairs[index].Item1 && index - 1 >= 0)
{
index--;
Logger.Log(LogLevel.Information, "LODController:EvaluateLodByHeight", $"Lower Pair found (altAboveGnd: {altAboveGnd} | index: {index} | lod: {lodPairs[index].Item2})");
return lodPairs[index].Item2;
}
return result;
}
}
public int VerticalAverage()
{
return verticalStats.Sum();
@ -289,60 +159,6 @@ namespace MSFS2020_AutoFPS
return verticalStatsVS.Average();
}
private void FindPairs()
{
Logger.Log(LogLevel.Information, "LODController:FindPairs", $"Finding Pairs (onGround: {Model.OnGround} | tlod: {tlod} | olod: {olod})");
if (!Model.OnGround)
{
int result = 0;
for (int i = 0; i < Model.PairsTLOD[Model.SelectedProfile].Count; i++)
{
if (altAboveGnd > Model.PairsTLOD[Model.SelectedProfile][i].Item1)
result = i;
}
Model.CurrentPairTLOD = result;
Logger.Log(LogLevel.Information, "LODController:FindPairs", $"TLOD Index {result}");
if (Model.ForceEvaluation || tlod != Model.PairsTLOD[Model.SelectedProfile][result].Item2)
{
Logger.Log(LogLevel.Information, "LODController:FindPairs", $"Setting TLOD {Model.PairsTLOD[Model.SelectedProfile][result].Item2}");
Model.MemoryAccess.SetTLOD(Model.PairsTLOD[Model.SelectedProfile][result].Item2);
}
result = 0;
for (int i = 0; i < Model.PairsOLOD[Model.SelectedProfile].Count; i++)
{
if (altAboveGnd > Model.PairsOLOD[Model.SelectedProfile][i].Item1)
result = i;
}
Model.CurrentPairOLOD = result;
Logger.Log(LogLevel.Information, "LODController:FindPairs", $"OLOD Index {result}");
if (Model.ForceEvaluation || olod != Model.PairsOLOD[Model.SelectedProfile][result].Item2)
{
Logger.Log(LogLevel.Information, "LODController:FindPairs", $"Setting OLOD {Model.PairsOLOD[Model.SelectedProfile][result].Item2}");
Model.MemoryAccess.SetOLOD(Model.PairsOLOD[Model.SelectedProfile][result].Item2);
}
}
else
{
int result = 0;
Model.CurrentPairTLOD = result;
if (Model.ForceEvaluation || tlod != Model.PairsTLOD[Model.SelectedProfile][result].Item2)
{
Logger.Log(LogLevel.Information, "LODController:FindPairs", $"Setting TLOD {Model.PairsTLOD[Model.SelectedProfile][result].Item2}");
Model.MemoryAccess.SetTLOD(Model.PairsTLOD[Model.SelectedProfile][result].Item2);
}
Model.CurrentPairOLOD = result;
if (Model.ForceEvaluation || olod != Model.PairsOLOD[Model.SelectedProfile][result].Item2)
{
Logger.Log(LogLevel.Information, "LODController:FindPairs", $"Setting OLOD {Model.PairsOLOD[Model.SelectedProfile][result].Item2}");
Model.MemoryAccess.SetOLOD(Model.PairsOLOD[Model.SelectedProfile][result].Item2);
}
}
ResetFPSMode(false);
FirstStart = false;
}
public float GetAverageFPS()
{
if (Model.MemoryAccess.IsFgModeActive())

View File

@ -30,22 +30,15 @@
<add key="olodPairs4" value="0:200|1000:150|2000:100|3000:50" />
<add key="tlodPairs5" value="0:100|1500:150|5000:200" />
<add key="olodPairs5" value="0:100|2500:150|7500:200" />
<add key="useTargetFps" value="false" />
<add key="targetFpsIndex" value="0" />
<add key="useExpertOptions" value="false" />
<add key="targetFps" value="40" />
<add key="FpsTolerance" value="5" />
<add key="constraintTicks" value="60" />
<add key="constraintDelayTicks" value="1" />
<add key="decreaseTlod" value="50" />
<add key="decreaseOlod" value="50" />
<add key="minLod" value="100" />
<add key="DecCloudQ" value="false" />
<add key="DecCloudQ" value="true" />
<add key="GroundTLODChanges" value="true" />
<add key="CloudRecoveryTLOD" value="100" />
<add key="minTLod" value="50" />
<add key="maxTLod" value="200" />
<add key="LodStepMax" value="false" />
<add key="LodStepMaxInc" value="5" />
<add key="LodStepMaxDec" value="5" />
<add key="offsetPointerCloudQ" value="0x44" />
<add key="offsetPointerCloudQVr" value="0x108" />
<add key="offsetPointerVrMode" value="0x1C" />

View File

@ -25,7 +25,6 @@ Work</Description>
</PropertyGroup>
<ItemGroup>
<None Remove="Dev Notes.txt" />
<None Remove="icon.ico" />
</ItemGroup>

View File

@ -81,12 +81,13 @@
</GroupBox>
</StackPanel>
<StackPanel Orientation="Vertical" Grid.Row="3" HorizontalAlignment="Center" Width="402">
<StackPanel Orientation="Vertical" Grid.Row="2" HorizontalAlignment="Center" Width="402">
<GroupBox BorderBrush="DarkGray" BorderThickness="1" Margin="10,8,10,8">
<GroupBox.Header>General</GroupBox.Header>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="369*"/>
<ColumnDefinition Width="369*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="6*"/>
@ -95,19 +96,25 @@
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Margin="0,0,0,34" Grid.RowSpan="2"/>
<StackPanel Grid.Row="1" Grid.Column="0" Orientation="Horizontal" Margin="0,8,0,0" Grid.ColumnSpan="2">
<CheckBox x:Name="chkOpenWindow" VerticalContentAlignment="Center" Click="chkOpenWindow_Click" Content="Open Window on App Start" Height="15" Width="337"/>
<Label Name="lblTargetFPS" Content="Target FPS" MinWidth="100"/>
<TextBox x:Name="txtTargetFPS" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Height="24" MaxHeight="24" MinHeight="24" Width="42" LostFocus="TextBox_LostFocus" KeyUp="TextBox_KeyUp" Margin="0,0,30,0"/>
</StackPanel>
<StackPanel Grid.Row="1" Grid.Column="1" Orientation="Horizontal" Margin="0,8,0,0" Grid.ColumnSpan="2">
<CheckBox Name="chkUseExpertOptions" VerticalContentAlignment="Center" Height="24" MaxHeight="24" MinHeight="24" Click="chkUseExpertOptions_Click">Use Expert Options</CheckBox>
</StackPanel>
<StackPanel Grid.Row="2" Grid.Column="0" Orientation="Horizontal" Margin="0,8,0,0">
<Label Name="lblIsVR" MinWidth="50" VerticalContentAlignment="Center" Content=""/>
<Label x:Name="lblsimCompatible" MinWidth="50" VerticalContentAlignment="Center" Content=""/>
<Label Name="lblStatusMessage" MinWidth="50" VerticalContentAlignment="Center" Content=""/>
<TextBlock x:Name="lblappUrl" VerticalAlignment="Center"> <Hyperlink NavigateUri="https://github.com/ResetXPDR/MSFS_AutoLOD/releases/latest" RequestNavigate="Hyperlink_RequestNavigate">
here</Hyperlink>
</TextBlock>
</StackPanel>
<StackPanel Grid.Row="2" Grid.Column="1" Orientation="Horizontal" Margin="0,8,0,0">
<CheckBox x:Name="chkOpenWindow" VerticalContentAlignment="Center" Click="chkOpenWindow_Click" Content="Open Window on App Start" Height="15" Width="220"/>
</StackPanel>
</Grid>
</GroupBox>
</StackPanel>
<StackPanel Orientation="Vertical" Grid.Column="0" Grid.Row="2">
<StackPanel Name="stkpnlMSFSSettings" Orientation="Vertical" Grid.Column="0" Grid.Row="3">
<GroupBox BorderBrush="DarkGray" BorderThickness="1" Margin="10,8,10,8">
<GroupBox.Header>MSFS Settings</GroupBox.Header>
<Grid Margin="0,2,0,2">
@ -121,11 +128,10 @@
</Grid.RowDefinitions>
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal" Margin="0,8,0,0">
<Label Content="Target FPS" MinWidth="100"/>
<TextBox x:Name="txtTargetFPS" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Height="24" MaxHeight="24" MinHeight="24" Width="42" LostFocus="TextBox_LostFocus" KeyUp="TextBox_KeyUp" Margin="0,0,30,0"/>
<Label Content="FPS Tolerance" MinWidth="100"/>
<Label Content="FPS Tolerance" MinWidth="95"/>
<TextBox x:Name="txtFPSTolerance" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Height="24" MaxHeight="24" MinHeight="24" Width="42" LostFocus="TextBox_LostFocus" KeyUp="TextBox_KeyUp" Margin="5,0,0,0"/>
<Label Content="%"/>
<CheckBox x:Name="chkGroundTLODChanges" Margin="15,0,0,0" VerticalContentAlignment="Center" Click="chkGroundTLODChanges_Click" Width="159" Content="TLOD changes on ground" Checked="chkGroundTLODChanges_Checked" Padding="4,0,0,0"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,4,0,0">
<Label Content="TLOD Minimum" MinWidth="100"/>
@ -133,7 +139,7 @@
<Label Content="TLOD Maximum" MinWidth="100"/>
<TextBox x:Name="txtMaxTLod" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Height="24" MaxHeight="24" MinHeight="24" Width="42" LostFocus="TextBox_LostFocus" KeyUp="TextBox_KeyUp" Margin="5,0,0,0"/>
</StackPanel>
<StackPanel Grid.Row="1" Grid.Column="0" Orientation="Horizontal" Margin="0,2,0,0">
<StackPanel Grid.Row="1" Grid.Column="0" Orientation="Horizontal" Margin="0,2,0,0" Visibility="Collapsed">
<Label Name="lblLodStepMax" VerticalContentAlignment="Center" Width ="96" Padding="5,5,0,5">TLOD Steps</Label>
<TextBox Name="txtLodStepMaxInc" Margin="4,0,0,0" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Height="24" MaxHeight="24" MinHeight="24" Width="42" LostFocus="TextBox_LostFocus" KeyUp="TextBox_KeyUp" TextChanged="txtLodStepMaxInc_TextChanged"></TextBox>
<Label VerticalContentAlignment="Center" Width ="133" Padding="5,5,0,5">Up</Label>
@ -150,8 +156,6 @@
</Grid>
</GroupBox>
</StackPanel>
</Grid>
</Viewbox>
</Window>

View File

@ -40,10 +40,10 @@ namespace MSFS2020_AutoFPS
assemblyVersion = assemblyVersion[0..assemblyVersion.LastIndexOf('.')];
Title += " (" + assemblyVersion + (serviceModel.TestVersion ? "-concept_demo" : "")+ ")";
//FillIndices(dgTlodPairs);
//FillIndices(dgOlodPairs);
if (serviceModel.UseExpertOptions) stkpnlMSFSSettings.Visibility = Visibility.Visible;
else stkpnlMSFSSettings.Visibility = Visibility.Collapsed;
timer = new DispatcherTimer
timer = new DispatcherTimer
{
Interval = TimeSpan.FromSeconds(1)
};
@ -58,26 +58,22 @@ namespace MSFS2020_AutoFPS
{
if ((serviceModel.TestVersion && LatestAppVersion >= currentAppVersion) || LatestAppVersion > currentAppVersion)
{
lblsimCompatible.Content = "Newer app version " + (latestAppVersionStr) + " now available";
lblsimCompatible.Foreground = new SolidColorBrush(Colors.Green);
lblappUrl.Visibility = Visibility.Visible;
lblStatusMessage.Content = "Newer app version " + (latestAppVersionStr) + " now available";
lblStatusMessage.Foreground = new SolidColorBrush(Colors.Green);
}
else
{
if (serviceModel.TestVersion)
{
lblsimCompatible.Content = latestAppVersionStr + " version is latest formal release. Check link works";
lblsimCompatible.Foreground = new SolidColorBrush(Colors.Green);
lblappUrl.Visibility = Visibility.Visible;
}
else
{
lblsimCompatible.Content = "Latest app version is installed";
lblsimCompatible.Foreground = new SolidColorBrush(Colors.Green);
}
lblStatusMessage.Content = "Latest app version is installed";
lblStatusMessage.Foreground = new SolidColorBrush(Colors.Green);
}
}
}
if (serviceModel.TestVersion)
{
lblStatusMessage.Content = "Concept demo version";
lblStatusMessage.Foreground = new SolidColorBrush(Colors.Green);
}
}
public static string GetFinalRedirect(string url)
{
@ -142,41 +138,14 @@ namespace MSFS2020_AutoFPS
protected void LoadSettings()
{
chkOpenWindow.IsChecked = serviceModel.OpenWindow;
//chkUseTargetFPS.IsChecked = serviceModel.UseTargetFPS;
//cbProfile.SelectedIndex = serviceModel.SelectedProfile;
//dgTlodPairs.ItemsSource = serviceModel.PairsTLOD[serviceModel.SelectedProfile].ToDictionary(x => x.Item1, x => x.Item2);
//dgOlodPairs.ItemsSource = serviceModel.PairsOLOD[serviceModel.SelectedProfile].ToDictionary(x => x.Item1, x => x.Item2);
chkUseExpertOptions.IsChecked = serviceModel.UseExpertOptions;
txtTargetFPS.Text = Convert.ToString(serviceModel.TargetFPS, CultureInfo.CurrentUICulture);
txtFPSTolerance.Text = Convert.ToString(serviceModel.FPSTolerance, CultureInfo.CurrentUICulture);
//txtDecreaseTlod.Text = Convert.ToString(serviceModel.DecreaseTLOD, CultureInfo.CurrentUICulture);
//txtDecreaseOlod.Text = Convert.ToString(serviceModel.DecreaseOLOD, CultureInfo.CurrentUICulture);
txtMinTLod.Text = Convert.ToString(serviceModel.MinTLOD, CultureInfo.CurrentUICulture);
txtMaxTLod.Text = Convert.ToString(serviceModel.MaxTLOD, CultureInfo.CurrentUICulture);
//txtConstraintTicks.Text = Convert.ToString(serviceModel.ConstraintTicks, CultureInfo.CurrentUICulture);
//txtConstraintDelayTicks.Text = Convert.ToString(serviceModel.ConstraintDelayTicks, CultureInfo.CurrentUICulture);
chkDecCloudQ.IsChecked = serviceModel.DecCloudQ;
chkGroundTLODChanges.IsChecked = serviceModel.GroundTLODChanges;
txtCloudRecoveryTLOD.Text = Convert.ToString(serviceModel.CloudRecoveryTLOD, CultureInfo.CurrentUICulture);
txtLodStepMaxInc.Text = Convert.ToString(serviceModel.LodStepMaxInc, CultureInfo.CurrentUICulture);
txtLodStepMaxDec.Text = Convert.ToString(serviceModel.LodStepMaxDec, CultureInfo.CurrentUICulture);
}
protected static void FillIndices(DataGrid dataGrid)
{
DataGridTextColumn column0 = new()
{
Header = "#",
Width = 16
};
Binding bindingColumn0 = new()
{
RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(DataGridRow), 1),
Converter = new RowToIndexConvertor()
};
column0.Binding = bindingColumn0;
dataGrid.Columns.Add(column0);
}
protected void UpdateStatus()
@ -208,7 +177,7 @@ namespace MSFS2020_AutoFPS
protected float GetAverageFPS()
{
if (serviceModel.MemoryAccess != null && serviceModel.MemoryAccess.IsFgModeActive())
if (serviceModel.MemoryAccess != null && serviceModel.MemoryAccess.IsFgModeActive() && serviceModel.MemoryAccess.IsActiveWindowMSFS())
return IPCManager.SimConnect.GetAverageFPS() * 2.0f;
else
return IPCManager.SimConnect.GetAverageFPS();
@ -223,30 +192,69 @@ namespace MSFS2020_AutoFPS
if (serviceModel.MemoryAccess != null)
{
lblappUrl.Visibility = Visibility.Hidden;
lblStatusMessage.Foreground = new SolidColorBrush(Colors.Black);
lblSimTLOD.Content = serviceModel.MemoryAccess.GetTLOD_PC().ToString("F0");
lblSimOLOD.Content = serviceModel.MemoryAccess.GetOLOD_PC().ToString("F0");
if (serviceModel.MemoryAccess.IsVrModeActive())
{
lblSimCloudQs.Content = CloudQualityLabel(serviceModel.MemoryAccess.GetCloudQ_VR());
lblIsVR.Content = "VR Mode active";
}
else
{
lblSimCloudQs.Content = CloudQualityLabel(serviceModel.MemoryAccess.GetCloudQ_PC());
lblIsVR.Content = "PC Mode" + (serviceModel.MemoryAccess.IsFgModeActive() ? " & FG" : "") + " active";
}
if (serviceModel.MemoryAccess.MemoryWritesAllowed())
{
lblsimCompatible.Visibility = Visibility.Hidden;
lblStatusMessage.Content = serviceModel.MemoryAccess.IsDX12() ? "DX 12 | " : " DX11 | ";
if (serviceModel.MemoryAccess.IsVrModeActive())
{
lblSimOLOD.Content = serviceModel.MemoryAccess.GetOLOD_VR().ToString("F0");
lblSimCloudQs.Content = CloudQualityLabel(serviceModel.MemoryAccess.GetCloudQ_VR());
lblStatusMessage.Content += " VR Mode";
}
else
{
lblSimOLOD.Content = serviceModel.MemoryAccess.GetOLOD_PC().ToString("F0");
lblSimCloudQs.Content = CloudQualityLabel(serviceModel.MemoryAccess.GetCloudQ_PC());
lblStatusMessage.Content += " PC Mode";
lblStatusMessage.Content += (serviceModel.MemoryAccess.IsFgModeActive() ? (serviceModel.MemoryAccess.IsActiveWindowMSFS() ? " | FG Active" : " | FG Inactive") : "");
}
}
else
{
lblsimCompatible.Content = "Incompatible MSFS version - Sim Values read only";
lblsimCompatible.Foreground = new SolidColorBrush(Colors.Red);
lblStatusMessage.Content = "Incompatible MSFS version - Sim Values read only";
lblStatusMessage.Foreground = new SolidColorBrush(Colors.Red);
}
if (serviceModel.IsSessionRunning)
{
float MinTLOD = serviceModel.MinTLOD;
float MaxTLOD = serviceModel.MaxTLOD;
if (serviceModel.UseExpertOptions)
{
MinTLOD = serviceModel.MinTLOD;
MaxTLOD = serviceModel.MaxTLOD;
}
else
{
if (serviceModel.MemoryAccess.IsVrModeActive())
{
MinTLOD = Math.Max(serviceModel.DefaultTLOD_VR * 0.5f, 10);
MaxTLOD = serviceModel.DefaultTLOD_VR * 2.0f;
}
else
{
MinTLOD = Math.Max(serviceModel.DefaultTLOD * 0.5f, 10);
MaxTLOD = serviceModel.DefaultTLOD * 2.0f;
}
}
if (serviceModel.MemoryAccess.IsFgModeActive()) lblTargetFPS.Content = "Target FG FPS";
else lblTargetFPS.Content = "Target FPS";
if (GetAverageFPS() < serviceModel.TargetFPS && serviceModel.MemoryAccess.GetTLOD_PC() == MinTLOD)
lblSimFPS.Foreground = new SolidColorBrush(Colors.Red);
else if (GetAverageFPS() > serviceModel.TargetFPS && serviceModel.MemoryAccess.GetTLOD_PC() == MaxTLOD)
lblSimFPS.Foreground = new SolidColorBrush(Colors.DarkGreen);
else lblSimFPS.Foreground = new SolidColorBrush(Colors.Black);
if (serviceModel.MemoryAccess.GetTLOD_PC() == MinTLOD) lblSimTLOD.Foreground = new SolidColorBrush(Colors.Red);
else if (serviceModel.MemoryAccess.GetTLOD_PC() == MaxTLOD) lblSimTLOD.Foreground = new SolidColorBrush(Colors.Green);
else if (serviceModel.tlod_step) lblSimTLOD.Foreground = new SolidColorBrush(Colors.Orange);
else lblSimTLOD.Foreground = new SolidColorBrush(Colors.Black);
if (serviceModel.DecCloudQ && serviceModel.DecCloudQActive) lblSimCloudQs.Foreground = new SolidColorBrush(Colors.Red);
else lblSimCloudQs.Foreground = new SolidColorBrush(Colors.Black);
}
else lblSimFPS.Foreground = new SolidColorBrush(Colors.Black);
}
else
{
@ -254,29 +262,6 @@ namespace MSFS2020_AutoFPS
lblSimOLOD.Content = "n/a";
lblSimCloudQs.Content = "n/a";
}
if (serviceModel.UseTargetFPS && serviceModel.IsSessionRunning)
{
if (GetAverageFPS() < serviceModel.TargetFPS)
lblSimFPS.Foreground = new SolidColorBrush(Colors.Red);
else
lblSimFPS.Foreground = new SolidColorBrush(Colors.DarkGreen);
}
else
{
lblSimFPS.Foreground = new SolidColorBrush(Colors.Black);
}
lblSimTLOD.Foreground = new SolidColorBrush(Colors.Black);
lblSimCloudQs.Foreground = new SolidColorBrush(Colors.Black);
if (serviceModel.MemoryAccess != null)
{
if (serviceModel.MemoryAccess.GetTLOD_PC() == serviceModel.MinTLOD) lblSimTLOD.Foreground = new SolidColorBrush(Colors.Red);
else if (serviceModel.MemoryAccess.GetTLOD_PC() == serviceModel.MaxTLOD) lblSimTLOD.Foreground = new SolidColorBrush(Colors.Green);
else if (serviceModel.tlod_step) lblSimTLOD.Foreground = new SolidColorBrush(Colors.Orange);
}
if (serviceModel.DecCloudQ && serviceModel.DecCloudQActive) lblSimCloudQs.Foreground = new SolidColorBrush(Colors.Red);
}
protected void UpdateAircraftValues()
@ -303,23 +288,11 @@ namespace MSFS2020_AutoFPS
}
}
protected static void UpdateIndex(DataGrid grid, List<(float, float)> pairs, int index)
{
if (index >= 0 && index < pairs.Count)
grid.SelectedIndex = index;
}
protected void OnTick(object sender, EventArgs e)
{
UpdateStatus();
UpdateLiveValues();
UpdateAircraftValues();
//if (serviceModel.IsSessionRunning)
//{
// UpdateIndex(dgTlodPairs, serviceModel.PairsTLOD[serviceModel.SelectedProfile], serviceModel.CurrentPairTLOD);
// UpdateIndex(dgOlodPairs, serviceModel.PairsOLOD[serviceModel.SelectedProfile], serviceModel.CurrentPairOLOD);
//}
}
protected void Window_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
@ -344,11 +317,13 @@ namespace MSFS2020_AutoFPS
Hide();
}
//private void chkUseTargetFPS_Click(object sender, RoutedEventArgs e)
//{
// serviceModel.SetSetting("useTargetFps", chkUseTargetFPS.IsChecked.ToString().ToLower());
// LoadSettings();
//}
private void chkUseExpertOptions_Click(object sender, RoutedEventArgs e)
{
serviceModel.SetSetting("useExpertOptions", chkUseExpertOptions.IsChecked.ToString().ToLower());
LoadSettings();
if (serviceModel.UseExpertOptions) stkpnlMSFSSettings.Visibility = Visibility.Visible;
else stkpnlMSFSSettings.Visibility = Visibility.Collapsed;
}
private void chkOpenWindow_Click(object sender, RoutedEventArgs e)
{
@ -356,6 +331,11 @@ namespace MSFS2020_AutoFPS
LoadSettings();
}
private void chkGroundTLODChanges_Click(object sender, RoutedEventArgs e)
{
serviceModel.SetSetting("GroundTLODChanges", chkGroundTLODChanges.IsChecked.ToString().ToLower());
LoadSettings();
}
private void chkDecCloudQ_Click(object sender, RoutedEventArgs e)
{
serviceModel.SetSetting("DecCloudQ", chkDecCloudQ.IsChecked.ToString().ToLower());
@ -395,21 +375,6 @@ namespace MSFS2020_AutoFPS
key = "FpsTolerance";
intValue = true;
break;
case "txtDecreaseTlod":
key = "decreaseTlod";
break;
case "txtDecreaseOlod":
key = "decreaseOlod";
break;
case "txtConstraintTicks":
key = "constraintTicks";
intValue = true;
break;
case "txtConstraintDelayTicks":
key = "constraintDelayTicks";
intValue = true;
zeroAllowed = true;
break;
case "txtCloudRecoveryTLOD":
key = "CloudRecoveryTLOD";
intValue = true;
@ -421,14 +386,14 @@ namespace MSFS2020_AutoFPS
case "txtMaxTLod":
key = "maxTLod";
break;
case "txtLodStepMaxInc":
key = "LodStepMaxInc";
intValue = true;
break;
case "txtLodStepMaxDec":
key = "LodStepMaxDec";
intValue = true;
break;
//case "txtLodStepMaxInc":
// key = "LodStepMaxInc";
// intValue = true;
// break;
//case "txtLodStepMaxDec":
// key = "LodStepMaxDec";
// intValue = true;
// break;
default:
key = "";
break;
@ -454,112 +419,6 @@ namespace MSFS2020_AutoFPS
LoadSettings();
}
private static void SetPairTextBox(DataGrid sender, TextBox alt, TextBox value, ref int index)
{
if (sender.SelectedIndex == -1 || sender.SelectedItem == null)
return;
var item = (KeyValuePair<float, float>)sender.SelectedItem;
alt.Text = Convert.ToString((int)item.Key, CultureInfo.CurrentUICulture);
value.Text = Convert.ToString(item.Value, CultureInfo.CurrentUICulture);
index = sender.SelectedIndex;
}
//private void dgTlodPairs_MouseDoubleClick(object sender, MouseButtonEventArgs e)
//{
// SetPairTextBox(dgTlodPairs, txtTlodAlt, txtTlodValue, ref editPairTLOD);
//}
//private void dgOlodPairs_MouseDoubleClick(object sender, MouseButtonEventArgs e)
//{
// SetPairTextBox(dgOlodPairs, txtOlodAlt, txtOlodValue, ref editPairOLOD);
//}
private void ChangeLodPair(ref int pairIndex, TextBox alt, TextBox value, List<(float, float)> pairs)
{
if (pairIndex == -1)
return;
if (pairIndex == 0 && alt.Text != "0")
alt.Text = "0";
if (int.TryParse(alt.Text, CultureInfo.InvariantCulture, out int agl) && float.TryParse(value.Text, new RealInvariantFormat(value.Text), out float lod)
&& pairIndex < pairs.Count && agl >= 0 && lod >= serviceModel.SimMinLOD)
{
var oldPair = pairs[pairIndex];
pairs[pairIndex] = (agl, lod);
if (pairs.Count(pair => pair.Item1 == agl) > 1)
pairs[pairIndex] = oldPair;
serviceModel.SavePairs();
}
LoadSettings();
alt.Text = "";
value.Text = "";
pairIndex = -1;
}
//private void btnTlodChange_Click(object sender, RoutedEventArgs e)
//{
// ChangeLodPair(ref editPairTLOD, txtTlodAlt, txtTlodValue, serviceModel.PairsTLOD[serviceModel.SelectedProfile]);
//}
//private void btnOlodChange_Click(object sender, RoutedEventArgs e)
//{
// ChangeLodPair(ref editPairOLOD, txtOlodAlt, txtOlodValue, serviceModel.PairsOLOD[serviceModel.SelectedProfile]);
//}
private void AddLodPair(ref int pairIndex, TextBox alt, TextBox value, List<(float, float)> pairs)
{
if (int.TryParse(alt.Text, CultureInfo.InvariantCulture, out int agl) && float.TryParse(value.Text, new RealInvariantFormat(value.Text), out float lod)
&& agl >= 0 && lod >= serviceModel.SimMinLOD
&& !pairs.Any(pair => pair.Item1 == agl))
{
pairs.Add((agl, lod));
ServiceModel.SortTupleList(pairs);
serviceModel.SavePairs();
}
LoadSettings();
alt.Text = "";
value.Text = "";
pairIndex = -1;
}
//private void btnTlodAdd_Click(object sender, RoutedEventArgs e)
//{
// AddLodPair(ref editPairTLOD, txtTlodAlt, txtTlodValue, serviceModel.PairsTLOD[serviceModel.SelectedProfile]);
//}
//private void btnOlodAdd_Click(object sender, RoutedEventArgs e)
//{
// AddLodPair(ref editPairOLOD, txtOlodAlt, txtOlodValue, serviceModel.PairsOLOD[serviceModel.SelectedProfile]);
//}
private void RemoveLoadPair(ref int pairIndex, TextBox alt, TextBox value, List<(float, float)> pairs)
{
if (pairIndex < 1 || pairIndex >= pairs.Count)
return;
pairs.RemoveAt(pairIndex);
ServiceModel.SortTupleList(pairs);
serviceModel.SavePairs();
LoadSettings();
alt.Text = "";
value.Text = "";
pairIndex = -1;
}
//private void btnTlodRemove_Click(object sender, RoutedEventArgs e)
//{
// RemoveLoadPair(ref editPairTLOD, txtTlodAlt, txtTlodValue, serviceModel.PairsTLOD[serviceModel.SelectedProfile]);
//}
//private void btnOlodRemove_Click(object sender, RoutedEventArgs e)
//{
// RemoveLoadPair(ref editPairOLOD, txtOlodAlt, txtOlodValue, serviceModel.PairsOLOD[serviceModel.SelectedProfile]);
//}
private void txtLodStepMaxInc_TextChanged(object sender, TextChangedEventArgs e)
{
@ -574,7 +433,11 @@ namespace MSFS2020_AutoFPS
{
}
private void chkGroundTLODChanges_Checked(object sender, RoutedEventArgs e)
{
}
private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
{
try
@ -604,39 +467,4 @@ namespace MSFS2020_AutoFPS
}
}
}
public class RowToIndexConvertor : MarkupExtension, IValueConverter
{
static RowToIndexConvertor convertor;
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value != null && value is DataGridRow row)
{
return row.GetIndex();
}
else
{
return -1;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
convertor ??= new RowToIndexConvertor();
return convertor;
}
public RowToIndexConvertor()
{
}
}
}

View File

@ -181,7 +181,7 @@ namespace MSFS2020_AutoFPS
[DllImport("user32.dll")]
static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
private bool IsActiveWindowMSFS()
public bool IsActiveWindowMSFS()
{
const int nChars = 256;
string activeWindowTitle;
@ -196,11 +196,16 @@ namespace MSFS2020_AutoFPS
}
return false;
}
public bool IsDX12()
{
return isDX12;
}
public bool IsFgModeActive()
{
try
{
if (isDX12 && !Model.MemoryAccess.IsVrModeActive() && IsActiveWindowMSFS())
if (isDX12 && !Model.MemoryAccess.IsVrModeActive())
return MemoryInterface.ReadMemory<byte>(addrFgMode) == 1;
else return false;
}

View File

@ -118,12 +118,9 @@ namespace MSFS2020_AutoFPS
if (true && IPCManager.IsSimRunning())
{
// Logger.Log(LogLevel.Information, "ServiceController:ServiceLoop", $"Sim still running, resetting LODs to {Model.DefaultTLOD} / {Model.DefaultOLOD} and VR {Model.DefaultTLOD_VR} / {Model.DefaultOLOD_VR}");
Logger.Log(LogLevel.Information, "ServiceController:ServiceLoop", $"Sim still running, resetting TLODs to PC / VR {Model.DefaultTLOD} / {Model.DefaultTLOD_VR}");
Model.MemoryAccess.SetTLOD_PC(Model.DefaultTLOD);
Model.MemoryAccess.SetTLOD_VR(Model.DefaultTLOD_VR);
//Model.MemoryAccess.SetOLOD_PC(Model.DefaultOLOD);
//Model.MemoryAccess.SetOLOD_VR(Model.DefaultOLOD_VR);
Logger.Log(LogLevel.Information, "ServiceController:ServiceLoop", $"Sim still running, resetting cloud quality to {Model.DefaultCloudQ} / VR {Model.DefaultCloudQ_VR}");
Model.MemoryAccess.SetCloudQ(Model.DefaultCloudQ);
Model.MemoryAccess.SetCloudQ_VR(Model.DefaultCloudQ_VR);

View File

@ -28,11 +28,12 @@ namespace MSFS2020_AutoFPS
public List<List<(float, float)>> PairsOLOD { get; set; }
public int CurrentPairOLOD;
public bool fpsMode { get; set; }
public bool UseTargetFPS { get; set; }
public bool UseExpertOptions { get; set; }
public int TargetFPS { get; set; }
public int FPSTolerance { get; set; }
public int CloudRecoveryTLOD { get; set; }
public bool DecCloudQActive { get; set; }
public bool GroundTLODChanges { get; set; }
public int ConstraintTicks { get; set; }
public int ConstraintDelayTicks { get; set; }
public float DecreaseTLOD { get; set; }
@ -91,10 +92,11 @@ namespace MSFS2020_AutoFPS
ConfigVersion = Convert.ToInt32(ConfigurationFile.GetSetting("ConfigVersion", "1"));
WaitForConnect = Convert.ToBoolean(ConfigurationFile.GetSetting("waitForConnect", "true"));
OpenWindow = Convert.ToBoolean(ConfigurationFile.GetSetting("openWindow", "true"));
DecCloudQ = Convert.ToBoolean(ConfigurationFile.GetSetting("DecCloudQ", "false"));
DecCloudQ = Convert.ToBoolean(ConfigurationFile.GetSetting("DecCloudQ", "true"));
GroundTLODChanges = Convert.ToBoolean(ConfigurationFile.GetSetting("GroundTLODChanges", "true"));
SimBinary = Convert.ToString(ConfigurationFile.GetSetting("simBinary", "FlightSimulator"));
SimModule = Convert.ToString(ConfigurationFile.GetSetting("simModule", "WwiseLibPCx64P.dll"));
UseTargetFPS = Convert.ToBoolean(ConfigurationFile.GetSetting("useTargetFps", "true"));
UseExpertOptions = Convert.ToBoolean(ConfigurationFile.GetSetting("useExpertOptions", "false"));
TargetFPS = Convert.ToInt32(ConfigurationFile.GetSetting("targetFps", "40"));
FPSTolerance = Convert.ToInt32(ConfigurationFile.GetSetting("FpsTolerance", "5"));
CloudRecoveryTLOD = Convert.ToInt32(ConfigurationFile.GetSetting("CloudRecoveryTLOD", "100"));