mirror of
https://github.com/hawkeye-stan/msfs-popout-panel-manager.git
synced 2024-12-26 22:32:01 +00:00
commit
d85f43e67f
22 changed files with 225 additions and 135 deletions
|
@ -11,9 +11,9 @@
|
|||
<PackageProjectUrl>https://github.com/hawkeye-stan/msfs-popout-panel-manager</PackageProjectUrl>
|
||||
<RootNamespace>MSFSPopoutPanelManager.DomainModel</RootNamespace>
|
||||
<Platforms>x64</Platforms>
|
||||
<Version>4.1.1.0</Version>
|
||||
<AssemblyVersion>4.1.1.0</AssemblyVersion>
|
||||
<FileVersion>4.1.1.0</FileVersion>
|
||||
<Version>4.1.2.0</Version>
|
||||
<AssemblyVersion>4.1.2.0</AssemblyVersion>
|
||||
<FileVersion>4.1.2.0</FileVersion>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<DebugType>Embedded</DebugType>
|
||||
<Configurations>Debug;Release;Local</Configurations>
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace MSFSPopoutPanelManager.DomainModel.Profile
|
|||
{
|
||||
public FloatingPanel()
|
||||
{
|
||||
PropertyChanged += FloatingPanel_PropertyChanged; ;
|
||||
PropertyChanged += FloatingPanel_PropertyChanged;
|
||||
}
|
||||
|
||||
private void FloatingPanel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
|
|
|
@ -127,5 +127,8 @@ namespace MSFSPopoutPanelManager.DomainModel.Profile
|
|||
return $"Left: {PanelSource.X} / Top: {PanelSource.Y}";
|
||||
}
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public MonitorInfo FullScreenMonitorInfo { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -256,6 +256,7 @@
|
|||
<TextBlock Style="{StaticResource TxtBlockDisableWhenLocked}" ToolTip="Add in-game menu bar panels such as VFR Map, Checklist, ATC, etc. to profile to enable panel size and location management and touch support">Include in-game menu bar panels for pop out management and touch screen support</TextBlock>
|
||||
</WrapPanel>
|
||||
|
||||
|
||||
<WrapPanel Margin="0,8,0,0">
|
||||
<ToggleButton
|
||||
IsChecked="{Binding ActiveProfile.ProfileSetting.NumPadConfig.IsEnabled, Mode=TwoWay, NotifyOnTargetUpdated=True}"
|
||||
|
|
|
@ -46,22 +46,22 @@ namespace MSFSPopoutPanelManager.MainApp.AppUserControl
|
|||
|
||||
private void IncludeInGamePanel_TargetUpdated(object sender, DataTransferEventArgs e)
|
||||
{
|
||||
_viewModel.IncludeInGamePanelUpdatedCommand.Execute(null);
|
||||
_viewModel.IncludeInGamePanelUpdatedCommand?.Execute(null);
|
||||
}
|
||||
|
||||
private void AddHudBar_TargetUpdated(object sender, DataTransferEventArgs e)
|
||||
{
|
||||
_viewModel.AddHudBarUpdatedCommand.Execute(null);
|
||||
_viewModel.AddHudBarUpdatedCommand?.Execute(null);
|
||||
}
|
||||
|
||||
private void AddRefocusDisplay_TargetUpdated(object sender, DataTransferEventArgs e)
|
||||
{
|
||||
_viewModel.RefocusDisplayUpdatedCommand.Execute(null);
|
||||
_viewModel.RefocusDisplayUpdatedCommand?.Execute(null);
|
||||
}
|
||||
|
||||
private void AddNumPad_TargetUpdated(object sender, DataTransferEventArgs e)
|
||||
{
|
||||
_viewModel.AddNumPadUpdatedCommand.Execute(null);
|
||||
_viewModel.AddNumPadUpdatedCommand?.Execute(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
using System.Windows.Interop;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
@ -26,6 +27,7 @@ namespace MSFSPopoutPanelManager.MainApp.AppWindow
|
|||
StateChanged += AppWindow_StateChanged;
|
||||
WindowActionManager.OnPopOutManagerAlwaysOnTopChanged += (_, e) => { Topmost = e; };
|
||||
MouseLeftButtonDown += (_, _) => DragMove();
|
||||
|
||||
}
|
||||
|
||||
private void AppWindow_Loaded(object sender, RoutedEventArgs e)
|
||||
|
|
|
@ -14,9 +14,9 @@
|
|||
<RootNamespace>MSFSPopoutPanelManager.MainApp</RootNamespace>
|
||||
<ApplicationIcon>logo.ico</ApplicationIcon>
|
||||
<Platforms>x64</Platforms>
|
||||
<Version>4.1.1.0</Version>
|
||||
<AssemblyVersion>4.1.1.0</AssemblyVersion>
|
||||
<FileVersion>4.1.1.0</FileVersion>
|
||||
<Version>4.1.2.0</Version>
|
||||
<AssemblyVersion>4.1.2.0</AssemblyVersion>
|
||||
<FileVersion>4.1.2.0</FileVersion>
|
||||
<DebugType>embedded</DebugType>
|
||||
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
|
||||
<!-- Publishing options -->
|
||||
|
|
|
@ -4,7 +4,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
|||
-->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Configuration>Local</Configuration>
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
<PublishDir>..\..\..\publish\master</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
using MSFSPopoutPanelManager.DomainModel.DynamicLod;
|
||||
using MSFSPopoutPanelManager.DomainModel.Setting;
|
||||
using MSFSPopoutPanelManager.Shared;
|
||||
using MSFSPopoutPanelManager.SimConnectAgent;
|
||||
using MSFSPopoutPanelManager.WindowsAgent;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
@ -17,12 +16,9 @@ namespace MSFSPopoutPanelManager.Orchestration
|
|||
private const int PROCESS_VM_WRITE = 0x0020;
|
||||
private const long OFFSET_MODULE_BASE =0x004B2368;
|
||||
private const long OFFSET_POINTER_MAIN = 0x3D0;
|
||||
private const long OFFSET_POINTER_TLOD_VR = 0x114;
|
||||
private const long OFFSET_POINTER_TLOD = 0xC;
|
||||
private const long OFFSET_POINTER_OLOD = 0xC;
|
||||
private const long OFFSET_POINTER_CLOUDQ = 0x44;
|
||||
private const long OFFSET_POINTER_CLOUDQ_VR = 0x108;
|
||||
private const long OFFSET_POINTER_VR_MODE = 0x1C;
|
||||
private const long OFFSET_POINTER_CLOUD_QUALITY = 0x44;
|
||||
private const long OFFSET_POINTER_FG_MODE = 0x4A;
|
||||
private const long OFFSET_POINTER_ANSIO_FILTER = -0x18;
|
||||
private const long OFFSET_POINTER_WATER_WAVES = 0x3C;
|
||||
|
@ -34,19 +30,15 @@ namespace MSFSPopoutPanelManager.Orchestration
|
|||
|
||||
private long _addressTlod;
|
||||
private long _addressOlod;
|
||||
private long _addressTlodVr;
|
||||
private long _addressOlodVr;
|
||||
private long _addressCloudQ;
|
||||
private long _addressCloudQVr;
|
||||
private long _addressVrMode;
|
||||
private long _addressFgMode;
|
||||
|
||||
private DynamicLodSetting DynamicLodSetting => AppSettingData.ApplicationSetting.DynamicLodSetting;
|
||||
|
||||
private DynamicLodSimData SimData => FlightSimData.DynamicLodSimData;
|
||||
private DynamicLodSimData DynamicLodSimData => FlightSimData.DynamicLodSimData;
|
||||
|
||||
private DateTime _lastLodUpdateTime = DateTime.Now;
|
||||
private bool _isDecreasedCloudQualityActive = false;
|
||||
private bool _isDecreasedCloudQualityActive;
|
||||
|
||||
public DynamicLodOrchestrator(SharedStorage sharedStorage) : base(sharedStorage) {}
|
||||
|
||||
|
@ -70,13 +62,9 @@ namespace MSFSPopoutPanelManager.Orchestration
|
|||
|
||||
if (_addressTlod > 0)
|
||||
{
|
||||
_addressTlodVr = ReadMemory<long>(_addressTlod) + OFFSET_POINTER_TLOD_VR;
|
||||
_addressTlod = ReadMemory<long>(_addressTlod) + OFFSET_POINTER_TLOD;
|
||||
_addressOlod = _addressTlod + OFFSET_POINTER_OLOD;
|
||||
_addressOlodVr = _addressTlodVr + OFFSET_POINTER_OLOD;
|
||||
_addressCloudQ = _addressTlod + OFFSET_POINTER_CLOUDQ;
|
||||
_addressCloudQVr = _addressCloudQ + OFFSET_POINTER_CLOUDQ_VR;
|
||||
_addressVrMode = _addressTlod - OFFSET_POINTER_VR_MODE;
|
||||
_addressCloudQ = _addressTlod + OFFSET_POINTER_CLOUD_QUALITY;
|
||||
_addressFgMode = _addressTlod - OFFSET_POINTER_FG_MODE;
|
||||
|
||||
if (!MemoryBoundaryTest())
|
||||
|
@ -99,9 +87,8 @@ namespace MSFSPopoutPanelManager.Orchestration
|
|||
|
||||
if (DynamicLodSetting.ResetEnabled)
|
||||
{
|
||||
var isVr = ReadIsVr();
|
||||
WriteMemory(isVr ? _addressTlodVr : _addressTlod, DynamicLodSetting.ResetTlod / 100.0f);
|
||||
WriteMemory(isVr ? _addressOlodVr : _addressOlod, DynamicLodSetting.ResetOlod / 100.0f);
|
||||
WriteMemory(_addressTlod, DynamicLodSetting.ResetTlod / 100.0f);
|
||||
WriteMemory(_addressOlod, DynamicLodSetting.ResetOlod / 100.0f);
|
||||
}
|
||||
|
||||
_isActive = false;
|
||||
|
@ -109,19 +96,19 @@ namespace MSFSPopoutPanelManager.Orchestration
|
|||
Debug.WriteLine($"Reset to custom LOD: TLOD: {DynamicLodSetting.ResetTlod}, OLOD: {DynamicLodSetting.ResetOlod}");
|
||||
}
|
||||
|
||||
public int ReadTlod(bool isVr = false)
|
||||
public int ReadTlod()
|
||||
{
|
||||
return Convert.ToInt32(ReadMemory<float>(isVr ? _addressTlodVr : _addressTlod) * 100.0f);
|
||||
return Convert.ToInt32(ReadMemory<float>(_addressTlod) * 100.0f);
|
||||
}
|
||||
|
||||
public int ReadOlod(bool isVr = false)
|
||||
public int ReadOlod()
|
||||
{
|
||||
return Convert.ToInt32(ReadMemory<float>(isVr ? _addressOlodVr : _addressOlod) * 100.0f);
|
||||
return Convert.ToInt32(ReadMemory<float>(_addressOlod) * 100.0f);
|
||||
}
|
||||
|
||||
public string ReadCloudQuality(bool isVr = false)
|
||||
public string ReadCloudQuality()
|
||||
{
|
||||
return ReadCloudQualitySimValue(isVr) switch
|
||||
return ReadCloudQualitySimValue() switch
|
||||
{
|
||||
0 => "Low",
|
||||
1 => "Medium",
|
||||
|
@ -131,33 +118,25 @@ namespace MSFSPopoutPanelManager.Orchestration
|
|||
};
|
||||
}
|
||||
|
||||
public int ReadCloudQualitySimValue(bool isVr = false)
|
||||
public int ReadCloudQualitySimValue()
|
||||
{
|
||||
return Convert.ToInt32(ReadMemory<int>(isVr ? _addressCloudQVr : _addressCloudQ));
|
||||
return Convert.ToInt32(ReadMemory<int>(_addressCloudQ));
|
||||
}
|
||||
|
||||
public bool ReadIsVr()
|
||||
public bool ReadIsFg()
|
||||
{
|
||||
return ReadMemory<int>(_addressVrMode) == 1;
|
||||
}
|
||||
|
||||
public bool ReadIsFg(bool isVr)
|
||||
{
|
||||
if (isVr)
|
||||
return false;
|
||||
|
||||
return ReadMemory<byte>(_addressFgMode) == 1;
|
||||
}
|
||||
|
||||
public void UpdateLod(bool isVr)
|
||||
public void UpdateLod()
|
||||
{
|
||||
if (DateTime.Now - _lastLodUpdateTime <= TimeSpan.FromSeconds(1))
|
||||
if (!FlightSimData.IsFlightStarted || !FlightSimData.IsInCockpit)
|
||||
return;
|
||||
|
||||
if (DateTime.Now - _lastLodUpdateTime <= TimeSpan.FromSeconds(3))
|
||||
return;
|
||||
|
||||
if (!FlightSimData.IsFlightStarted || !FlightSimData.IsInCockpit || (DynamicLodSetting.PauseOutsideCockpitView && FlightSimData.CameraState != CameraState.Cockpit))
|
||||
return;
|
||||
|
||||
var deltaFps = SimData.Fps - DynamicLodSetting.TargetedFps;
|
||||
var deltaFps = DynamicLodSimData.Fps - DynamicLodSetting.TargetedFps;
|
||||
if (Math.Abs(deltaFps) < DynamicLodSetting.TargetedFps * DynamicLodSetting.FpsTolerance / 100.0) // within FPS tolerance
|
||||
return;
|
||||
|
||||
|
@ -246,10 +225,9 @@ namespace MSFSPopoutPanelManager.Orchestration
|
|||
private bool MemoryBoundaryTest()
|
||||
{
|
||||
// Boundary check a few known setting memory addresses to see if any fail which likely indicates MSFS memory map has changed
|
||||
if (ReadTlod() < 10 || ReadTlod() > 1000 || ReadTlod(true) < 10 || ReadTlod(true) > 1000
|
||||
|| ReadOlod() < 10 || ReadOlod() > 1000 || ReadOlod(true) < 10 || ReadOlod(true) > 1000
|
||||
|| ReadCloudQuality() == "N/A" || ReadCloudQuality(true) == "N/A"
|
||||
|| ReadMemory<int>(_addressVrMode) < 0 || ReadMemory<int>(_addressVrMode) > 1
|
||||
if (ReadTlod() < 10 || ReadTlod() > 1000 || ReadTlod() < 10 || ReadTlod() > 1000
|
||||
|| ReadOlod() < 10 || ReadOlod() > 1000 || ReadOlod() < 10 || ReadOlod() > 1000
|
||||
|| ReadCloudQuality() == "N/A" || ReadCloudQuality() == "N/A"
|
||||
|| ReadMemory<int>(_addressTlod + OFFSET_POINTER_ANSIO_FILTER) < 1 || ReadMemory<int>(_addressTlod + OFFSET_POINTER_ANSIO_FILTER) > 16
|
||||
|| !(ReadMemory<int>(_addressTlod + OFFSET_POINTER_WATER_WAVES) == 128 || ReadMemory<int>(_addressTlod + OFFSET_POINTER_WATER_WAVES) == 256 || ReadMemory<int>(_addressTlod + OFFSET_POINTER_WATER_WAVES) == 512))
|
||||
{
|
||||
|
@ -259,12 +237,12 @@ namespace MSFSPopoutPanelManager.Orchestration
|
|||
return true;
|
||||
}
|
||||
|
||||
private void SetTlod(int deltaFps, bool isVr = false)
|
||||
private void SetTlod(int deltaFps)
|
||||
{
|
||||
var tlodStep = Math.Max(5, Math.Abs(deltaFps / 2));
|
||||
var newTlod = SimData.Tlod + Math.Sign(deltaFps) * tlodStep;
|
||||
var tlodStep = Math.Max(10, Math.Abs(deltaFps / 2));
|
||||
var newTlod = DynamicLodSimData.Tlod + Math.Sign(deltaFps) * tlodStep;
|
||||
|
||||
if (DynamicLodSetting.TlodMinOnGround && SimData.AltAboveGround <= DynamicLodSetting.AltTlodBase)
|
||||
if (DynamicLodSetting.TlodMinOnGround && DynamicLodSimData.AltAboveGround <= DynamicLodSetting.AltTlodBase)
|
||||
{
|
||||
newTlod = DynamicLodSetting.TlodMin;
|
||||
}
|
||||
|
@ -277,17 +255,17 @@ namespace MSFSPopoutPanelManager.Orchestration
|
|||
newTlod = DynamicLodSetting.TlodMax;
|
||||
}
|
||||
|
||||
if (ReadTlod(isVr) == newTlod)
|
||||
if (ReadTlod() == newTlod)
|
||||
return;
|
||||
|
||||
// Adjust cloud quality if applicable
|
||||
if (DynamicLodSetting.DecreaseCloudQuality && (!DynamicLodSetting.TlodMinOnGround && !(SimData.AltAboveGround <= DynamicLodSetting.AltTlodBase)))
|
||||
if (DynamicLodSetting.DecreaseCloudQuality && (!DynamicLodSetting.TlodMinOnGround && !(DynamicLodSimData.AltAboveGround <= DynamicLodSetting.AltTlodBase)))
|
||||
{
|
||||
switch (deltaFps)
|
||||
{
|
||||
case < 0 when newTlod < DynamicLodSetting.CloudRecoveryTlod && !_isDecreasedCloudQualityActive:
|
||||
_isDecreasedCloudQualityActive = true;
|
||||
WriteMemory(isVr ? _addressCloudQVr : _addressCloudQ, ReadCloudQualitySimValue(isVr) - 1);
|
||||
WriteMemory(_addressCloudQ, ReadCloudQualitySimValue() - 1);
|
||||
|
||||
_lastLodUpdateTime =
|
||||
_lastLodUpdateTime.AddSeconds(2); // Add extra delay for cloud setting to take effect
|
||||
|
@ -296,7 +274,7 @@ namespace MSFSPopoutPanelManager.Orchestration
|
|||
return;
|
||||
case > 0 when newTlod >= DynamicLodSetting.CloudRecoveryTlod && _isDecreasedCloudQualityActive:
|
||||
_isDecreasedCloudQualityActive = false;
|
||||
WriteMemory(isVr ? _addressCloudQVr : _addressCloudQ, ReadCloudQualitySimValue(isVr) + 1);
|
||||
WriteMemory(_addressCloudQ, ReadCloudQualitySimValue() + 1);
|
||||
|
||||
_lastLodUpdateTime = _lastLodUpdateTime.AddSeconds(2);
|
||||
Debug.WriteLine("New Cloud Quality written - 3.");
|
||||
|
@ -306,31 +284,31 @@ namespace MSFSPopoutPanelManager.Orchestration
|
|||
}
|
||||
|
||||
Debug.WriteLine($"New TLOD written - {newTlod}.");
|
||||
WriteMemory(isVr ? _addressTlodVr : _addressTlod, newTlod / 100.0f);
|
||||
WriteMemory(_addressTlod, newTlod / 100.0f);
|
||||
}
|
||||
|
||||
private void SetOlod(bool isVr = false)
|
||||
private void SetOlod()
|
||||
{
|
||||
int newOlod;
|
||||
|
||||
if (SimData.AltAboveGround < DynamicLodSetting.AltOlodBase)
|
||||
if (DynamicLodSimData.AltAboveGround < DynamicLodSetting.AltOlodBase)
|
||||
{
|
||||
newOlod = DynamicLodSetting.OlodBase;
|
||||
}
|
||||
else if (SimData.AltAboveGround > DynamicLodSetting.AltOlodTop)
|
||||
else if (DynamicLodSimData.AltAboveGround > DynamicLodSetting.AltOlodTop)
|
||||
{
|
||||
newOlod = DynamicLodSetting.OlodTop;
|
||||
}
|
||||
else
|
||||
{
|
||||
newOlod = Convert.ToInt32(DynamicLodSetting.OlodBase - (DynamicLodSetting.OlodBase - DynamicLodSetting.OlodTop) * (SimData.AltAboveGround - DynamicLodSetting.AltOlodBase) / (DynamicLodSetting.AltOlodTop - DynamicLodSetting.AltOlodBase));
|
||||
newOlod = Convert.ToInt32(DynamicLodSetting.OlodBase - (DynamicLodSetting.OlodBase - DynamicLodSetting.OlodTop) * (DynamicLodSimData.AltAboveGround - DynamicLodSetting.AltOlodBase) / (DynamicLodSetting.AltOlodTop - DynamicLodSetting.AltOlodBase));
|
||||
}
|
||||
|
||||
if (ReadOlod(isVr) == newOlod)
|
||||
if (ReadOlod() == newOlod)
|
||||
return;
|
||||
|
||||
Debug.WriteLine($"New OLOD written - {newOlod}.");
|
||||
WriteMemory(isVr ? _addressOlodVr : _addressOlod, newOlod / 100.0f);
|
||||
WriteMemory(_addressOlod, newOlod / 100.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace MSFSPopoutPanelManager.Orchestration
|
|||
private System.Timers.Timer _msfsGameExitDetectionTimer;
|
||||
private SimConnectProvider _simConnectProvider;
|
||||
|
||||
private DynamicLodOrchestrator _dynamicLodOrchestrator;
|
||||
private readonly DynamicLodOrchestrator _dynamicLodOrchestrator;
|
||||
private bool _isTurnedOnPower;
|
||||
private bool _isTurnedOnAvionics;
|
||||
|
||||
|
@ -72,22 +72,39 @@ namespace MSFSPopoutPanelManager.Orchestration
|
|||
MapHudBarSimConnectData(e);
|
||||
};
|
||||
|
||||
var _lastDynamicLodPause = DateTime.Now;
|
||||
var _isDynamicLodPausePrevously = true;
|
||||
var _lastDyanmicLodUpdatedTime = DateTime.Now;
|
||||
|
||||
_simConnectProvider.OnSimConnectDataDynamicLodRefreshed += (_, e) =>
|
||||
{
|
||||
if (!AppSettingData.ApplicationSetting.DynamicLodSetting.IsEnabled || !FlightSimData.IsFlightStarted)
|
||||
return;
|
||||
|
||||
var isVr = _dynamicLodOrchestrator.ReadIsVr();
|
||||
MapDynamicLodSimConnectData(e, isVr);
|
||||
|
||||
var isPaused = (AppSettingData.ApplicationSetting.DynamicLodSetting.PauseWhenMsfsLoseFocus && !WindowActionManager.IsMsfsInFocus()) ||
|
||||
(AppSettingData.ApplicationSetting.DynamicLodSetting.PauseOutsideCockpitView && FlightSimData.CameraState != CameraState.Cockpit);
|
||||
|
||||
if (isPaused)
|
||||
if (_isDynamicLodPausePrevously && !isPaused)
|
||||
{
|
||||
if (DateTime.Now - _lastDynamicLodPause <= TimeSpan.FromSeconds(3))
|
||||
return;
|
||||
|
||||
_lastDynamicLodPause = DateTime.Now;
|
||||
_isDynamicLodPausePrevously = false;
|
||||
}
|
||||
else if (isPaused)
|
||||
{
|
||||
_isDynamicLodPausePrevously = true;
|
||||
return;
|
||||
|
||||
FlightSimData.DynamicLodSimData.Fps = FpsCalc.GetAverageFps(_dynamicLodOrchestrator.ReadIsFg(isVr) ? _currentFps * 2 : _currentFps);
|
||||
_dynamicLodOrchestrator.UpdateLod(isVr);
|
||||
}
|
||||
|
||||
if (DateTime.Now - _lastDyanmicLodUpdatedTime <= TimeSpan.FromSeconds(0.4)) // take FPS sample every 0.4 seconds
|
||||
return;
|
||||
|
||||
_lastDyanmicLodUpdatedTime = DateTime.Now;
|
||||
|
||||
MapDynamicLodSimConnectData(e);
|
||||
_dynamicLodOrchestrator.UpdateLod();
|
||||
};
|
||||
|
||||
_simConnectProvider.OnSimConnectDataEventFrameRefreshed += (_, e) =>
|
||||
|
@ -393,6 +410,7 @@ namespace MSFSPopoutPanelManager.Orchestration
|
|||
FlightSimData.IsFlightStarted = false;
|
||||
|
||||
StopDynamicLod();
|
||||
FpsCalc.Reset();
|
||||
FlightSimData.DynamicLodSimData.Clear();
|
||||
}
|
||||
|
||||
|
@ -492,7 +510,7 @@ namespace MSFSPopoutPanelManager.Orchestration
|
|||
FlightSimData.HudBarData.SimRate = newValue;
|
||||
}
|
||||
|
||||
private void MapDynamicLodSimConnectData(List<SimDataItem> simData, bool isVr)
|
||||
private void MapDynamicLodSimConnectData(List<SimDataItem> simData)
|
||||
{
|
||||
if (CompareSimConnectData(simData, SimDataDefinitions.PropName.PlaneAltAboveGround, FlightSimData.DynamicLodSimData.Agl, out var newValue))
|
||||
FlightSimData.DynamicLodSimData.Agl = newValue;
|
||||
|
@ -509,17 +527,19 @@ namespace MSFSPopoutPanelManager.Orchestration
|
|||
if (CompareSimConnectData(simData, SimDataDefinitions.PropName.SimOnGround, 1.0f, out newValue))
|
||||
FlightSimData.DynamicLodSimData.PlaneOnGround = Convert.ToBoolean(newValue);
|
||||
|
||||
var tlod = _dynamicLodOrchestrator.ReadTlod(isVr);
|
||||
var tlod = _dynamicLodOrchestrator.ReadTlod();
|
||||
if (FlightSimData.DynamicLodSimData.Tlod != tlod)
|
||||
FlightSimData.DynamicLodSimData.Tlod = tlod;
|
||||
|
||||
var olod = _dynamicLodOrchestrator.ReadOlod(isVr);
|
||||
var olod = _dynamicLodOrchestrator.ReadOlod();
|
||||
if (FlightSimData.DynamicLodSimData.Olod != olod)
|
||||
FlightSimData.DynamicLodSimData.Olod = olod;
|
||||
|
||||
var cloudQuality = _dynamicLodOrchestrator.ReadCloudQuality(isVr);
|
||||
var cloudQuality = _dynamicLodOrchestrator.ReadCloudQuality();
|
||||
if (FlightSimData.DynamicLodSimData.CloudQuality != cloudQuality)
|
||||
FlightSimData.DynamicLodSimData.CloudQuality = cloudQuality;
|
||||
|
||||
FlightSimData.DynamicLodSimData.Fps = FpsCalc.GetAverageFps(_dynamicLodOrchestrator.ReadIsFg() ? _currentFps * 2 : _currentFps);
|
||||
}
|
||||
|
||||
private int _currentFps;
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
<PackageProjectUrl>https://github.com/hawkeye-stan/msfs-popout-panel-manager</PackageProjectUrl>
|
||||
<RootNamespace>MSFSPopoutPanelManager.Orchestration</RootNamespace>
|
||||
<Platforms>x64</Platforms>
|
||||
<Version>4.1.1.0</Version>
|
||||
<AssemblyVersion>4.1.1.0</AssemblyVersion>
|
||||
<FileVersion>4.1.1.0</FileVersion>
|
||||
<Version>4.1.2.0</Version>
|
||||
<AssemblyVersion>4.1.2.0</AssemblyVersion>
|
||||
<FileVersion>4.1.2.0</FileVersion>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<DebugType>Embedded</DebugType>
|
||||
<Configurations>Debug;Release;Local</Configurations>
|
||||
|
|
|
@ -130,8 +130,15 @@ namespace MSFSPopoutPanelManager.Orchestration
|
|||
{
|
||||
InputEmulationManager.ToggleFullScreenPanel(panelConfig.PanelHandle);
|
||||
|
||||
if (!panelConfig.FullScreen)
|
||||
if (panelConfig.FullScreen)
|
||||
{
|
||||
WindowActionManager.SetHostMonitor(panelConfig);
|
||||
}
|
||||
else
|
||||
{
|
||||
WindowActionManager.MoveWindow(panelConfig.PanelHandle, panelConfig.Left, panelConfig.Top, panelConfig.Width, panelConfig.Height);
|
||||
panelConfig.FullScreenMonitorInfo = null;
|
||||
}
|
||||
}
|
||||
else if (configPropertyName == PanelConfigPropertyName.PanelName)
|
||||
{
|
||||
|
|
|
@ -122,7 +122,7 @@ namespace MSFSPopoutPanelManager.Orchestration
|
|||
StepAddHudBar();
|
||||
|
||||
StepAddNumPad();
|
||||
|
||||
|
||||
SetupRefocusDisplay();
|
||||
|
||||
StepApplyPanelConfig();
|
||||
|
@ -412,12 +412,6 @@ namespace MSFSPopoutPanelManager.Orchestration
|
|||
foreach (var panelConfig in ActiveProfile.PanelConfigs)
|
||||
{
|
||||
ApplyPanelConfig(panelConfig);
|
||||
|
||||
// Set title bar color
|
||||
if (AppSettingData.ApplicationSetting.PopOutSetting.PopOutTitleBarCustomization.IsEnabled && !panelConfig.FullScreen)
|
||||
{
|
||||
WindowActionManager.SetWindowTitleBarColor(panelConfig.PanelHandle, AppSettingData.ApplicationSetting.PopOutSetting.PopOutTitleBarCustomization.HexColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -516,11 +510,10 @@ namespace MSFSPopoutPanelManager.Orchestration
|
|||
|
||||
if (!panel.FullScreen)
|
||||
{
|
||||
// Apply always on top
|
||||
if (panel.AlwaysOnTop)
|
||||
// Set title bar color
|
||||
if (AppSettingData.ApplicationSetting.PopOutSetting.PopOutTitleBarCustomization.IsEnabled)
|
||||
{
|
||||
WindowActionManager.ApplyAlwaysOnTop(panel.PanelHandle, panel.PanelType, panel.AlwaysOnTop);
|
||||
Thread.Sleep(250);
|
||||
WindowActionManager.SetWindowTitleBarColor(panel.PanelHandle, AppSettingData.ApplicationSetting.PopOutSetting.PopOutTitleBarCustomization.HexColor);
|
||||
}
|
||||
|
||||
// Apply hide title bar
|
||||
|
@ -529,6 +522,13 @@ namespace MSFSPopoutPanelManager.Orchestration
|
|||
WindowActionManager.ApplyHidePanelTitleBar(panel.PanelHandle, true);
|
||||
Thread.Sleep(250);
|
||||
}
|
||||
|
||||
// Apply always on top (must apply this last)
|
||||
if (panel.AlwaysOnTop)
|
||||
{
|
||||
WindowActionManager.ApplyAlwaysOnTop(panel.PanelHandle, panel.PanelType, panel.AlwaysOnTop);
|
||||
Thread.Sleep(250);
|
||||
}
|
||||
}
|
||||
|
||||
if (panel.FullScreen && !panel.AlwaysOnTop && !panel.HideTitlebar)
|
||||
|
@ -536,6 +536,9 @@ namespace MSFSPopoutPanelManager.Orchestration
|
|||
Thread.Sleep(500);
|
||||
InputEmulationManager.ToggleFullScreenPanel(panel.PanelHandle);
|
||||
Thread.Sleep(250);
|
||||
|
||||
if (panel.TouchEnabled)
|
||||
WindowActionManager.SetHostMonitor(panel); // Set full screen coordinate for touch
|
||||
}
|
||||
|
||||
if (panel.FloatingPanel.IsEnabled && panel.FloatingPanel.HasKeyboardBinding && panel.FloatingPanel.IsHiddenOnStart)
|
||||
|
|
|
@ -1,15 +1,7 @@
|
|||
## Version 4.1.1
|
||||
## Version 4.1.2
|
||||
|
||||
* Added option to store POPM profiles and configuration files in your user's AppData Roaming folder instead of Documents folder. Hopefully, this solved the issue where OneDrive users are having issue with POPM files.
|
||||
* Added touch support for pop out when in full screen mode.
|
||||
|
||||
* Fixed POPM inability to close correctly when Keyboard Shortcuts preference is disabled.
|
||||
* Fixed pop out always on top issue where it sometimes does not work.
|
||||
|
||||
* Fixed issue where auto start option failed to retain CommandLine arguments in exe.xml file.
|
||||
|
||||
* Fixed issue where auto start does not work correctly for Steam version of MSFS since exe.xml file location has been moved by Steam installation.
|
||||
|
||||
* Added ability for full screen panel to work as floating panel. An example use case is to show and hide EFB as full screen using keyboard shortcut.
|
||||
|
||||
* Added dynamic LOD (my own implementation of AutoFPS) - this is totally experimental and unsupported. If you decide to use this version of dynamic LOD, you don't have to run multiple apps.
|
||||
|
||||
* Fixed various smaller bugs.
|
||||
* Improved dynamic LOD FPS detection and logic.
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
<PackageProjectUrl>https://github.com/hawkeye-stan/msfs-popout-panel-manager</PackageProjectUrl>
|
||||
<RootNamespace>MSFSPopoutPanelManager.Shared</RootNamespace>
|
||||
<Platforms>x64</Platforms>
|
||||
<Version>4.1.1.0</Version>
|
||||
<AssemblyVersion>4.1.1.0</AssemblyVersion>
|
||||
<FileVersion>4.1.1.0</FileVersion>
|
||||
<Version>4.1.2.0</Version>
|
||||
<AssemblyVersion>4.1.2.0</AssemblyVersion>
|
||||
<FileVersion>4.1.2.0</FileVersion>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<DebugType>Embedded</DebugType>
|
||||
<Configurations>Debug;Release;Local</Configurations>
|
||||
|
|
|
@ -5,32 +5,57 @@ namespace MSFSPopoutPanelManager.SimConnectAgent
|
|||
{
|
||||
public class FpsCalc
|
||||
{
|
||||
private const int FpsLen = 25;
|
||||
private static readonly float[] FpsStatistic = new float[FpsLen];
|
||||
private const int FPS_LEN = 5;
|
||||
private static readonly float[] FpsStatistic = new float[FPS_LEN];
|
||||
private static int _fpsIndex = -1;
|
||||
private static int _avgFps;
|
||||
private static int _ignoreFpsSpikeCount = 0;
|
||||
|
||||
public static int GetAverageFps(int newValue)
|
||||
{
|
||||
if (_fpsIndex == -1)
|
||||
{
|
||||
for (var i = 0; i < FpsLen; i++)
|
||||
// initialize FpsStatistic array
|
||||
for (var i = 0; i < FPS_LEN; i++)
|
||||
FpsStatistic[i] = newValue;
|
||||
|
||||
|
||||
_avgFps = Convert.ToInt32(newValue);
|
||||
_fpsIndex = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
var isSpike = Math.Abs(newValue - _avgFps) / (_avgFps * 1.0) > 0.1;
|
||||
|
||||
if (_ignoreFpsSpikeCount != 3 && isSpike) // if new FPS spikes more than 10%, ignore the value
|
||||
{
|
||||
_ignoreFpsSpikeCount++;
|
||||
return _avgFps;
|
||||
}
|
||||
|
||||
_ignoreFpsSpikeCount = 0;
|
||||
|
||||
var deltaFps = newValue - _avgFps;
|
||||
|
||||
if (deltaFps < 0 && Math.Abs(deltaFps) > _avgFps * 0.1) // FPS suddenly drops more than 10%
|
||||
{
|
||||
newValue += Math.Abs(deltaFps) / 2; // Let the new FPS to be only half the delta drop
|
||||
}
|
||||
|
||||
FpsStatistic[_fpsIndex] = newValue;
|
||||
_fpsIndex++;
|
||||
if (_fpsIndex >= FpsLen)
|
||||
if (_fpsIndex >= FPS_LEN)
|
||||
_fpsIndex = 0;
|
||||
|
||||
_avgFps = Convert.ToInt32(FpsStatistic.Sum() / FPS_LEN);
|
||||
}
|
||||
|
||||
return _avgFps;
|
||||
}
|
||||
|
||||
var fps = 0;
|
||||
if (_fpsIndex != -1)
|
||||
fps = Convert.ToInt32(FpsStatistic.Sum() / FpsLen);
|
||||
|
||||
return fps;
|
||||
public static void Reset()
|
||||
{
|
||||
_fpsIndex = -1;
|
||||
_avgFps = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
<PackageProjectUrl>https://github.com/hawkeye-stan/msfs-popout-panel-manager</PackageProjectUrl>
|
||||
<RootNamespace>MSFSPopoutPanelManager.SimConnectAgent</RootNamespace>
|
||||
<Platforms>x64</Platforms>
|
||||
<Version>4.1.1.0</Version>
|
||||
<AssemblyVersion>4.1.1.0</AssemblyVersion>
|
||||
<FileVersion>4.1.1.0</FileVersion>
|
||||
<Version>4.1.2.0</Version>
|
||||
<AssemblyVersion>4.1.2.0</AssemblyVersion>
|
||||
<FileVersion>4.1.2.0</FileVersion>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<DebugType>Embedded</DebugType>
|
||||
<Configurations>Debug;Release;Local</Configurations>
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
# Version History
|
||||
<hr/>
|
||||
|
||||
## Version 4.1.2
|
||||
|
||||
* Added touch support for pop out when in full screen mode.
|
||||
|
||||
* Fixed pop out always on top issue where it sometimes does not work.
|
||||
|
||||
* Improved dynamic LOD FPS detection and logic.
|
||||
|
||||
|
||||
## Version 4.1.1
|
||||
|
||||
* Added option to store POPM profiles and configuration files in your user's AppData Roaming folder instead of Documents folder. Hopefully, this solved the issue where OneDrive users are having issue with POPM files.
|
||||
|
|
|
@ -193,6 +193,23 @@ namespace MSFSPopoutPanelManager.WindowsAgent
|
|||
|
||||
return new Rectangle(rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top);
|
||||
}
|
||||
|
||||
public static IntPtr GetWindowHandle(string windowCaption)
|
||||
{
|
||||
IntPtr windowHandle = IntPtr.Zero;
|
||||
|
||||
EnumWindows((hwnd, _) =>
|
||||
{
|
||||
var caption = GetWindowText(hwnd);
|
||||
|
||||
if (caption == windowCaption)
|
||||
windowHandle = hwnd;
|
||||
|
||||
return true;
|
||||
}, 0);
|
||||
|
||||
return windowHandle;
|
||||
}
|
||||
}
|
||||
|
||||
public struct RECT
|
||||
|
|
|
@ -92,10 +92,8 @@ namespace MSFSPopoutPanelManager.WindowsAgent
|
|||
|
||||
// If touch point is within pop out panel boundaries and have touch enabled
|
||||
var panelConfig = ActiveProfile.PanelConfigs.FirstOrDefault(p => p.TouchEnabled &&
|
||||
(info.pt.X > p.Left
|
||||
&& info.pt.X < p.Left + p.Width
|
||||
&& info.pt.Y > p.Top + (p.HideTitlebar ? 5 : PANEL_MENUBAR_HEIGHT)
|
||||
&& info.pt.Y < p.Top + p.Height));
|
||||
((p.FullScreen && CheckWithinFullScreenCoordinate(p, info)) || CheckWithinWindowCoordinate(p, info)));
|
||||
|
||||
|
||||
if (panelConfig == null)
|
||||
return PInvoke.CallNextHookEx(_hHook, code, wParam, lParam);
|
||||
|
@ -218,5 +216,21 @@ namespace MSFSPopoutPanelManager.WindowsAgent
|
|||
|
||||
return PInvoke.CallNextHookEx(_hHook, code, wParam, lParam);
|
||||
}
|
||||
|
||||
private static bool CheckWithinWindowCoordinate(PanelConfig panelConfig, MSLLHOOKSTRUCT coor)
|
||||
{
|
||||
return coor.pt.X > panelConfig.Left
|
||||
&& coor.pt.X < panelConfig.Left + panelConfig.Width
|
||||
&& coor.pt.Y > panelConfig.Top + (panelConfig.HideTitlebar ? 5 : PANEL_MENUBAR_HEIGHT)
|
||||
&& coor.pt.Y < panelConfig.Top + panelConfig.Height;
|
||||
}
|
||||
|
||||
private static bool CheckWithinFullScreenCoordinate(PanelConfig panelConfig, MSLLHOOKSTRUCT coor)
|
||||
{
|
||||
return coor.pt.X > panelConfig.FullScreenMonitorInfo.X
|
||||
&& coor.pt.X < panelConfig.FullScreenMonitorInfo.X + panelConfig.FullScreenMonitorInfo.Width
|
||||
&& coor.pt.Y > panelConfig.FullScreenMonitorInfo.Y
|
||||
&& coor.pt.Y < panelConfig.FullScreenMonitorInfo.Y + panelConfig.FullScreenMonitorInfo.Height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,6 +49,8 @@ namespace MSFSPopoutPanelManager.WindowsAgent
|
|||
if (panelType == PanelType.PopOutManager)
|
||||
{
|
||||
OnPopOutManagerAlwaysOnTopChanged?.Invoke(null, alwaysOnTop);
|
||||
if(alwaysOnTop)
|
||||
PInvoke.SetWindowPos(hwnd, new IntPtr(PInvokeConstant.HWND_TOPMOST), 0, 0, 0, 0, PInvokeConstant.SWP_ALWAYS_ON_TOP);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -309,5 +311,22 @@ namespace MSFSPopoutPanelManager.WindowsAgent
|
|||
|
||||
return text.Substring(0, 26).Equals("Microsoft Flight Simulator", StringComparison.InvariantCultureIgnoreCase);
|
||||
}
|
||||
|
||||
public static void SetHostMonitor(PanelConfig panelConfig)
|
||||
{
|
||||
foreach (var screen in System.Windows.Forms.Screen.AllScreens)
|
||||
{
|
||||
if (screen.Bounds.IntersectsWith(new Rectangle(panelConfig.Left, panelConfig.Top, panelConfig.Width, panelConfig.Height)))
|
||||
panelConfig.FullScreenMonitorInfo =
|
||||
new MonitorInfo
|
||||
{
|
||||
Name = screen.DeviceName.Substring(screen.DeviceName.LastIndexOf("\\", StringComparison.Ordinal) + 1),
|
||||
X = screen.Bounds.X,
|
||||
Y = screen.Bounds.Y,
|
||||
Width = screen.Bounds.Width,
|
||||
Height = screen.Bounds.Height
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
<PackageProjectUrl>https://github.com/hawkeye-stan/msfs-popout-panel-manager</PackageProjectUrl>
|
||||
<RootNamespace>MSFSPopoutPanelManager.WindowsAgent</RootNamespace>
|
||||
<Platforms>x64</Platforms>
|
||||
<Version>4.1.1.0</Version>
|
||||
<AssemblyVersion>4.1.1.0</AssemblyVersion>
|
||||
<FileVersion>4.1.1.0</FileVersion>
|
||||
<Version>4.1.2.0</Version>
|
||||
<AssemblyVersion>4.1.2.0</AssemblyVersion>
|
||||
<FileVersion>4.1.2.0</FileVersion>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<DebugType>Embedded</DebugType>
|
||||
<Configurations>Debug;Release;Local</Configurations>
|
||||
|
|
Loading…
Reference in a new issue