diff --git a/G940LEDControl/Forms/MainFrm.dfm b/G940LEDControl/Forms/MainFrm.dfm index d27b513..d8a16ae 100644 --- a/G940LEDControl/Forms/MainFrm.dfm +++ b/G940LEDControl/Forms/MainFrm.dfm @@ -1,7 +1,7 @@ object MainForm: TMainForm Left = 0 Top = 0 - ActiveControl = cbProfileMenu + ActiveControl = cmbProfiles BorderIcons = [biSystemMenu, biMinimize] BorderStyle = bsSingle Caption = 'G940 LED Control' @@ -29,15 +29,11 @@ object MainForm: TMainForm Margins.Top = 8 Margins.Right = 8 Margins.Bottom = 8 - ActivePage = tsConfiguration + ActivePage = tsButtons Align = alClient TabOrder = 0 object tsButtons: TTabSheet Caption = ' Button assignment ' - ExplicitLeft = 0 - ExplicitTop = 0 - ExplicitWidth = 0 - ExplicitHeight = 0 DesignSize = ( 442 452) diff --git a/G940LEDControl/G940LEDControl.dproj b/G940LEDControl/G940LEDControl.dproj index 5bcedf3..1b17187 100644 --- a/G940LEDControl/G940LEDControl.dproj +++ b/G940LEDControl/G940LEDControl.dproj @@ -49,18 +49,17 @@ true + 7 rtl;dbrtl;$(DCC_UsePackage) Lib - 0 Bin ..\Shared;$(DCC_UnitSearchPath) true - 2 None G940LEDControl_Icon.ico Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;System.Win;$(DCC_Namespace) - CompanyName=X²Software;FileDescription=G940 LED Control;FileVersion=0.2.0.0;InternalName=;LegalCopyright=© 2011 X²Software;LegalTrademarks=;OriginalFilename=G940LEDControl.exe;ProductName=G940 LED Control;ProductVersion=0.2;Comments= - 1043 + CompanyName=X²Software;FileDescription=G940 LED Control;FileVersion=1.0.7.0;InternalName=;LegalCopyright=© 2011 - 2015 X²Software;LegalTrademarks=;OriginalFilename=G940LEDControl.exe;ProductName=G940 LED Control;ProductVersion=1.0;Comments= + 1033 G940LEDControl_Icon.ico @@ -71,7 +70,6 @@ false false Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - 1033 $(BDS)\bin\default_app.manifest @@ -82,12 +80,6 @@ RELEASE;$(DCC_Define) - 1 - 6 - 1 - 0 - CompanyName=X²Software;FileDescription=G940 LED Control;FileVersion=1.0.6.1;InternalName=;LegalCopyright=© 2011 X²Software;LegalTrademarks=;OriginalFilename=G940LEDControl.exe;ProductName=G940 LED Control;ProductVersion=1.0;Comments= - 1033 $(BDS)\bin\default_app.manifest @@ -105,7 +97,6 @@ false CompanyName=;FileDescription=;FileVersion=0.2.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=0.2;Comments= $(BDS)\bin\default_app.manifest - 1033 @@ -201,7 +192,9 @@ 1.0.0.0 - + + JVCL BDE Components + False diff --git a/G940LEDControl/G940LEDControl.res b/G940LEDControl/G940LEDControl.res index bc71e1a..b71b0cd 100644 Binary files a/G940LEDControl/G940LEDControl.res and b/G940LEDControl/G940LEDControl.res differ diff --git a/G940LEDControl/Units/FSXLEDFunction.pas b/G940LEDControl/Units/FSXLEDFunction.pas index cdb849f..891a6c6 100644 --- a/G940LEDControl/Units/FSXLEDFunction.pas +++ b/G940LEDControl/Units/FSXLEDFunction.pas @@ -82,6 +82,13 @@ type function GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass; override; end; + TFSXThrottleFunction = class(TCustomFSXFunction) + protected + function GetCategoryName: string; override; + procedure RegisterStates; override; + function GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass; override; + end; + { Control surfaces } TFSXFlapsFunction = class(TCustomFSXFunction) @@ -208,6 +215,19 @@ type end; + { ATC } + TFSXATCVisibilityFunction = class(TCustomMultiStateLEDFunction) + protected + procedure RegisterStates; override; + + function GetCategoryName: string; override; + function GetDisplayName: string; override; + function GetUID: string; override; + + function GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass; override; + end; + + implementation uses FSXLEDFunctionWorker, @@ -384,6 +404,29 @@ begin end; +{ TFSXThrottleFunction } +function TFSXThrottleFunction.GetCategoryName: string; +begin + Result := FSXCategoryEngines; +end; + + +procedure TFSXThrottleFunction.RegisterStates; +begin + RegisterState(TLEDState.Create(FSXStateUIDThrottleNoEngines, FSXStateDisplayNameThrottleNoThrottles, lcOff)); + RegisterState(TLEDState.Create(FSXStateUIDThrottleOff, FSXStateDisplayNameThrottleOff, lcGreen)); + RegisterState(TLEDState.Create(FSXStateUIDThrottlePartial, FSXStateDisplayNameThrottlePartial, lcAmber)); + RegisterState(TLEDState.Create(FSXStateUIDThrottleFull, FSXStateDisplayNameThrottleFull, lcRed)); + RegisterState(TLEDState.Create(FSXStateUIDThrottleReverse, FSXStateDisplayNameThrottleReverse, lcFlashingAmberNormal)); +end; + + +function TFSXThrottleFunction.GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass; +begin + Result := TFSXThrottleFunctionWorker; +end; + + { TFSXFlapsFunction } function TFSXFlapsFunction.GetCategoryName: string; begin @@ -617,4 +660,36 @@ begin Result := TFSXFuelFunctionWorker; end; + +{ TFSXATCFunction } +procedure TFSXATCVisibilityFunction.RegisterStates; +begin + RegisterState(TLEDState.Create(FSXStateUIDATCHidden, FSXStateDisplayNameATCHidden, lcGreen)); + RegisterState(TLEDState.Create(FSXStateUIDATCVisible, FSXStateDisplayNameATCVisible, lcFlashingAmberNormal)); +end; + + +function TFSXATCVisibilityFunction.GetCategoryName: string; +begin + Result := FSXCategoryATC; +end; + + +function TFSXATCVisibilityFunction.GetDisplayName: string; +begin + Result := FSXFunctionDisplayNameATCVisibility; +end; + + +function TFSXATCVisibilityFunction.GetUID: string; +begin + Result := FSXFunctionUIDATCVisibility; +end; + + +function TFSXATCVisibilityFunction.GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass; +begin + Result := TFSXATCVisibilityFunctionWorker; +end; + end. diff --git a/G940LEDControl/Units/FSXLEDFunctionProvider.pas b/G940LEDControl/Units/FSXLEDFunctionProvider.pas index 413eba0..0a0ad92 100644 --- a/G940LEDControl/Units/FSXLEDFunctionProvider.pas +++ b/G940LEDControl/Units/FSXLEDFunctionProvider.pas @@ -139,6 +139,7 @@ begin { Engines } RegisterFunction(TFSXEngineAntiIceFunction.Create( Self, FSXFunctionDisplayNameEngineAntiIce, FSXFunctionUIDEngineAntiIce)); RegisterFunction(TFSXEngineFunction.Create( Self, FSXFunctionDisplayNameEngine, FSXFunctionUIDEngine)); + RegisterFunction(TFSXThrottleFunction.Create( Self, FSXFunctionDisplayNameThrottle, FSXFunctionUIDThrottle)); { Control surfaces } RegisterFunction(TFSXFlapsFunction.Create( Self, FSXFunctionDisplayNameFlaps, FSXFunctionUIDFlaps)); @@ -167,6 +168,9 @@ begin { Fuel } RegisterFunction(TFSXFuelFunction.Create( Self, FSXFunctionDisplayNameFuel, FSXFunctionUIDFuel)); + + { ATC } + RegisterFunction(TFSXATCVisibilityFunction.Create(FSXProviderUID)); end; diff --git a/G940LEDControl/Units/FSXLEDFunctionWorker.pas b/G940LEDControl/Units/FSXLEDFunctionWorker.pas index 9f66012..a617df0 100644 --- a/G940LEDControl/Units/FSXLEDFunctionWorker.pas +++ b/G940LEDControl/Units/FSXLEDFunctionWorker.pas @@ -2,8 +2,12 @@ unit FSXLEDFunctionWorker; interface uses + OtlTaskControl, + FSXLEDFunctionProvider, - FSXSimConnectIntf; + FSXSimConnectIntf, + LEDFunction, + LEDFunctionIntf; type @@ -64,6 +68,12 @@ type procedure HandleData(AData: Pointer); override; end; + TFSXThrottleFunctionWorker = class(TCustomFSXFunctionWorker) + protected + procedure RegisterVariables(ADefinition: IFSXSimConnectDefinition); override; + procedure HandleData(AData: Pointer); override; + end; + { Control surfaces } TFSXFlapsFunctionWorker = class(TCustomFSXFunctionWorker) @@ -173,10 +183,23 @@ type end; + { ATC } + TFSXATCVisibilityFunctionWorker = class(TCustomLEDMultiStateFunctionWorker) + private + FMonitorTask: IOmniTaskControl; + public + constructor Create(const AProviderUID: string; const AFunctionUID: string; AStates: ILEDMultiStateFunction; ASettings: ILEDFunctionWorkerSettings; const APreviousState: string = ''); override; + destructor Destroy; override; + end; + + implementation uses System.Math, System.SysUtils, + Winapi.Windows, + + OtlTask, FSXResources, LEDStateIntf, @@ -455,6 +478,64 @@ begin end; +{ TFSXThrottleFunctionWorker } +procedure TFSXThrottleFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition); +var + engineIndex: Integer; + +begin + ADefinition.AddVariable('NUMBER OF ENGINES', FSX_UNIT_NUMBER, SIMCONNECT_DATAType_INT32); + + for engineIndex := 1 to FSX_MAX_ENGINES do + ADefinition.AddVariable(Format('GENERAL ENG THROTTLE LEVER POSITION:%d', [engineIndex]), FSX_UNIT_PERCENT, SIMCONNECT_DATAType_FLOAT64); +end; + + +procedure TFSXThrottleFunctionWorker.HandleData(AData: Pointer); +type + PThrottleData = ^TThrottleData; + TThrottleData = packed record + NumberOfEngines: Integer; + Position: array[1..FSX_MAX_ENGINES] of Double; + end; + +var + throttleData: PThrottleData; + reverse: Boolean; + totalPosition: Double; + engineIndex: Integer; + +begin + throttleData := AData; + + if throttleData^.NumberOfEngines > 0 then + begin + reverse := False; + totalPosition := 0; + + for engineIndex := 1 to throttleData^.NumberOfEngines do + begin + if throttleData^.Position[engineIndex] < 0 then + begin + reverse := True; + break; + end else + totalPosition := totalPosition + throttleData^.Position[engineIndex]; + end; + + if reverse then + SetCurrentState(FSXStateUIDThrottleReverse) + else + case Trunc(totalPosition / throttleData^.NumberOfEngines) of + 0..5: SetCurrentState(FSXStateUIDThrottleOff); + 95..100: SetCurrentState(FSXStateUIDThrottleFull); + else SetCurrentState(FSXStateUIDThrottlePartial); + end; + end else + SetCurrentState(FSXStateUIDThrottleNoEngines); +end; + + { TFSXFlapsFunctionWorker } procedure TFSXFlapsFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition); begin @@ -702,4 +783,88 @@ begin SetCurrentState(FSXStateUIDFuelNotAvailable); end; + +type + TFSXATCVisibilityStateChanged = reference to procedure(AVisible: Boolean); + + TFSXATCVisibilityTask = class(TOmniWorker) + private + FOnStateChanged: TFSXATCVisibilityStateChanged; + FVisible: Boolean; + public + constructor Create(AOnStateChanged: TFSXATCVisibilityStateChanged); + procedure Run; + end; + + +{ TFSXATCVisibilityFunctionWorker } +constructor TFSXATCVisibilityFunctionWorker.Create(const AProviderUID, AFunctionUID: string; AStates: ILEDMultiStateFunction; ASettings: ILEDFunctionWorkerSettings; const APreviousState: string); +begin + inherited Create(AProviderUID, AFunctionUID, AStates, ASettings, APreviousState); + + FMonitorTask := CreateTask(TFSXATCVisibilityTask.Create( + procedure(AVisible: Boolean) + begin + if AVisible then + SetCurrentState(FSXStateUIDATCVisible) + else + SetCurrentState(FSXStateUIDATCHidden); + end)) + .SetTimer(1, MSecsPerSec, @TFSXATCVisibilityTask.Run) + .Run; +end; + + +destructor TFSXATCVisibilityFunctionWorker.Destroy; +begin + FMonitorTask.Terminate; + FMonitorTask := nil; + + inherited Destroy; +end; + + +{ TFSXATCVisibilityTask } +constructor TFSXATCVisibilityTask.Create(AOnStateChanged: TFSXATCVisibilityStateChanged); +begin + inherited Create; + + FOnStateChanged := AOnStateChanged; + FVisible := False; +end; + + +procedure TFSXATCVisibilityTask.Run; +const + ClassNameMainWindow = 'FS98MAIN'; + ClassNameChildWindow = 'FS98CHILD'; + ClassNameFloatWindow = 'FS98FLOAT'; + WindowTitleATC = 'ATC Menu'; + +var + visible: Boolean; + mainWindow: THandle; + atcWindow: THandle; + +begin + { Docked } + atcWindow := 0; + mainWindow := FindWindow(ClassNameMainWindow, nil); + if mainWindow <> 0 then + atcWindow := FindWindowEx(mainWindow, 0, ClassNameChildWindow, WindowTitleATC); + + { Undocked } + if atcWindow = 0 then + atcWindow := FindWindow(ClassNameFloatWindow, WindowTitleATC); + + + visible := (atcWindow <> 0) and IsWindowVisible(atcWindow); + + if visible <> FVisible then + begin + FVisible := visible; + FOnStateChanged(visible); + end; +end; + end. diff --git a/G940LEDControl/Units/FSXResources.pas b/G940LEDControl/Units/FSXResources.pas index 55d1197..70a5507 100644 --- a/G940LEDControl/Units/FSXResources.pas +++ b/G940LEDControl/Units/FSXResources.pas @@ -12,6 +12,7 @@ const FSXCategoryLights = FSXCategory + ' - Lights'; FSXCategoryAutoPilot = FSXCategory + ' - Autopilot'; FSXCategoryRadios = FSXCategory + ' - Radios'; + FSXCategoryATC = FSXCategory + ' - ATC'; FSXStateUIDOn = 'on'; FSXStateUIDOff = 'off'; @@ -40,6 +41,22 @@ const FSXStateDisplayNameEngineOnFire = 'On fire'; + FSXFunctionUIDThrottle = 'throttle'; + FSXFunctionDisplayNameThrottle = 'Throttle'; + + FSXStateUIDThrottleNoEngines = 'noEngines'; + FSXStateUIDThrottleOff = 'off'; + FSXStateUIDThrottlePartial = 'partial'; + FSXStateUIDThrottleFull = 'full'; + FSXStateUIDThrottleReverse = 'reverse'; + + FSXStateDisplayNameThrottleNoThrottles = 'No engines'; + FSXStateDisplayNameThrottleOff = 'Off'; + FSXStateDisplayNameThrottlePartial = 'Partial'; + FSXStateDisplayNameThrottleFull = 'Full'; + FSXStateDisplayNameThrottleReverse = 'Reversed'; + + FSXFunctionUIDGear = 'gear'; FSXFunctionDisplayNameGear = 'Landing gear'; @@ -220,6 +237,16 @@ const FSXStateDisplayNameFuel75to100 = '75% - Full'; + FSXFunctionUIDATCVisibility = 'atcVisiblity'; + FSXFunctionDisplayNameATCVisibility = 'ATC Visibility (experimental)'; + + FSXStateUIDATCHidden = 'hidden'; + FSXStateUIDATCVisible = 'visible'; + + FSXStateDisplayNameATCHidden = 'Hidden'; + FSXStateDisplayNameATCVisible = 'Visible'; + + FSXMenuProfiles = 'G940 Profile'; FSXMenuProfileFormat = 'G940: %s';