1
0
mirror of synced 2024-11-22 10:03:51 +00:00

Fixed LEDs not changing color

Implemented landing/instrument lights and parking brake functions
This commit is contained in:
Mark van Renswoude 2012-01-04 22:22:51 +00:00
parent caec794f3b
commit 84aeb8daa2
5 changed files with 151 additions and 20 deletions

View File

@ -137,9 +137,9 @@ object MainForm: TMainForm
ItemHeight = 13 ItemHeight = 13
ItemIndex = 0 ItemIndex = 0
TabOrder = 1 TabOrder = 1
Text = '<Not assigned>' Text = 'Parking brake'
Items.Strings = ( Items.Strings = (
'<Not assigned>') 'Parking brake')
end end
object cmbFSXP3: TComboBox object cmbFSXP3: TComboBox
Left = 69 Left = 69
@ -152,9 +152,9 @@ object MainForm: TMainForm
ItemHeight = 13 ItemHeight = 13
ItemIndex = 0 ItemIndex = 0
TabOrder = 2 TabOrder = 2
Text = '<Not assigned>' Text = 'Landing lights'
Items.Strings = ( Items.Strings = (
'<Not assigned>') 'Landing lights')
end end
object cmbFSXP4: TComboBox object cmbFSXP4: TComboBox
Left = 69 Left = 69
@ -212,9 +212,9 @@ object MainForm: TMainForm
ItemHeight = 13 ItemHeight = 13
ItemIndex = 0 ItemIndex = 0
TabOrder = 6 TabOrder = 6
Text = '<Not assigned>' Text = 'Instrument lights'
Items.Strings = ( Items.Strings = (
'<Not assigned>') 'Instrument lights')
end end
object cmbFSXP8: TComboBox object cmbFSXP8: TComboBox
Left = 69 Left = 69

View File

@ -77,6 +77,7 @@ type
procedure EventMonitorMessage(const task: IOmniTaskControl; const msg: TOmniMessage); procedure EventMonitorMessage(const task: IOmniTaskControl; const msg: TOmniMessage);
procedure HandleDeviceStateMessage(ATask: IOmniTaskControl; AMessage: TOmniMessage); procedure HandleDeviceStateMessage(ATask: IOmniTaskControl; AMessage: TOmniMessage);
procedure HandleRunInMainThreadMessage(ATask: IOmniTaskControl; AMessage: TOmniMessage);
property EventMonitor: TOmniEventMonitor read FEventMonitor; property EventMonitor: TOmniEventMonitor read FEventMonitor;
property StateConsumerTask: IOmniTaskControl read FStateConsumerTask; property StateConsumerTask: IOmniTaskControl read FStateConsumerTask;
@ -133,6 +134,7 @@ begin
FinalizeStateProvider; FinalizeStateProvider;
StateConsumerTask.Terminate; StateConsumerTask.Terminate;
StateConsumerTask.WaitFor(INFINITE);
FStateConsumerTask := nil; FStateConsumerTask := nil;
end; end;
@ -221,14 +223,18 @@ end;
procedure TMainForm.UpdateMappingFSX; procedure TMainForm.UpdateMappingFSX;
begin begin
TLEDStateConsumer.SetFunction(StateConsumerTask, 1, FUNCTION_FSX_PARKINGBRAKE);
TLEDStateConsumer.SetFunction(StateConsumerTask, 2, FUNCTION_FSX_LANDINGLIGHTS);
TLEDStateConsumer.SetFunction(StateConsumerTask, 3, FUNCTION_FSX_GEAR); TLEDStateConsumer.SetFunction(StateConsumerTask, 3, FUNCTION_FSX_GEAR);
TLEDStateConsumer.SetFunction(StateConsumerTask, 6, FUNCTION_FSX_INSTRUMENTLIGHTS);
end; end;
procedure TMainForm.EventMonitorMessage(const task: IOmniTaskControl; const msg: TOmniMessage); procedure TMainForm.EventMonitorMessage(const task: IOmniTaskControl; const msg: TOmniMessage);
begin begin
case msg.MsgID of case msg.MsgID of
MSG_NOTIFY_DEVICESTATE: HandleDeviceStateMessage(task, msg); MSG_NOTIFY_DEVICESTATE: HandleDeviceStateMessage(task, msg);
MSG_RUN_IN_MAINTHREAD: HandleRunInMainThreadMessage(task, msg);
end; end;
end; end;
@ -251,6 +257,12 @@ begin
end; end;
procedure TMainForm.HandleRunInMainThreadMessage(ATask: IOmniTaskControl; AMessage: TOmniMessage);
begin
(AMessage.MsgData.AsInterface as IRunInMainThread).Execute;
end;
procedure TMainForm.btnFSXConnectClick(Sender: TObject); procedure TMainForm.btnFSXConnectClick(Sender: TObject);
begin begin
InitializeStateProvider(TFSXLEDStateProvider); InitializeStateProvider(TFSXLEDStateProvider);

View File

@ -1,5 +1,7 @@
unit FSXLEDStateProvider; unit FSXLEDStateProvider;
// ToDo check has gear (react to sim start, aircraft change, etc)
interface interface
uses uses
Classes, Classes,
@ -12,6 +14,9 @@ uses
const const
FUNCTION_FSX_GEAR = 1; FUNCTION_FSX_GEAR = 1;
FUNCTION_FSX_LANDINGLIGHTS = 2;
FUNCTION_FSX_INSTRUMENTLIGHTS = 3;
FUNCTION_FSX_PARKINGBRAKE = 4;
EXIT_ERROR_INITSIMCONNECT = 1; EXIT_ERROR_INITSIMCONNECT = 1;
EXIT_ERROR_CONNECT = 2; EXIT_ERROR_CONNECT = 2;
@ -29,6 +34,7 @@ type
procedure UpdateMap; procedure UpdateMap;
procedure HandleDispatch(AData: PSimConnectRecv); procedure HandleDispatch(AData: PSimConnectRecv);
function GetDataBoolean(var AData: Cardinal): Boolean;
function GetDataDouble(var AData: Cardinal): Double; function GetDataDouble(var AData: Cardinal): Double;
property SimConnectHandle: THandle read FSimConnectHandle; property SimConnectHandle: THandle read FSimConnectHandle;
@ -52,12 +58,21 @@ const
READY_TIMEOUT = 5000; READY_TIMEOUT = 5000;
DEFINITION_GEAR = 1; DEFINITION_GEAR = 1;
REQUEST_GEAR = 1; DEFINITION_LIGHTS = 2;
DEFINITION_INSTRUMENTLIGHTS = 3;
DEFINITION_PARKINGBRAKE = 4;
FSX_VARIABLE_GEARTOTALPCTEXTENDED = 'GEAR TOTAL PCT EXTENDED'; FSX_VARIABLE_GEARTOTALPCTEXTENDED = 'GEAR TOTAL PCT EXTENDED';
FSX_VARIABLE_LIGHTONSTATES = 'LIGHT ON STATES';
FSX_VARIABLE_PARKINGBRAKE = 'BRAKE PARKING INDICATOR';
FSX_UNIT_PERCENT = 'percent'; FSX_UNIT_PERCENT = 'percent';
FSX_UNIT_MASK = 'mask';
FSX_UNIT_BOOL = 'bool';
FSX_LIGHTON_LANDING = $0004;
FSX_LIGHTON_PANEL = $0020;
FSX_LIGHTON_CABIN = $0200;
{ TFSXLEDStateProvider } { TFSXLEDStateProvider }
@ -117,16 +132,47 @@ begin
if FUseFunctionGear then if FUseFunctionGear then
SimConnect_ClearDataDefinition(SimConnectHandle, DEFINITION_GEAR); SimConnect_ClearDataDefinition(SimConnectHandle, DEFINITION_GEAR);
FUseFunctionGear := Consumer.FunctionMap.HasFunction(FUNCTION_FSX_GEAR); FUseFunctionGear := Consumer.FunctionMap.HasFunction(FUNCTION_FSX_GEAR);
if FUseFunctionGear then if FUseFunctionGear then
begin begin
SimConnect_AddToDataDefinition(SimConnectHandle, DEFINITION_GEAR, SimConnect_AddToDataDefinition(SimConnectHandle, DEFINITION_GEAR,
FSX_VARIABLE_GEARTOTALPCTEXTENDED, FSX_VARIABLE_GEARTOTALPCTEXTENDED,
FSX_UNIT_PERCENT); FSX_UNIT_PERCENT);
SimConnect_RequestDataOnSimObject(SimConnectHandle, REQUEST_GEAR, SimConnect_RequestDataOnSimObject(SimConnectHandle, DEFINITION_GEAR,
DEFINITION_GEAR, DEFINITION_GEAR,
SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_OBJECT_ID_USER,
SIMCONNECT_PERIOD_SECOND, SIMCONNECT_PERIOD_SIM_FRAME,
SIMCONNECT_DATA_REQUEST_FLAG_CHANGED);
end;
// ToDo for other vars too!
// if FUseFunctionGear then
// SimConnect_ClearDataDefinition(SimConnectHandle, DEFINITION_GEAR);
if Consumer.FunctionMap.HasFunction(FUNCTION_FSX_LANDINGLIGHTS) or
Consumer.FunctionMap.HasFunction(FUNCTION_FSX_INSTRUMENTLIGHTS) then
begin
SimConnect_AddToDataDefinition(SimConnectHandle, DEFINITION_LIGHTS,
FSX_VARIABLE_LIGHTONSTATES,
FSX_UNIT_MASK,
SIMCONNECT_DATATYPE_INT32);
SimConnect_RequestDataOnSimObject(SimConnectHandle, DEFINITION_LIGHTS,
DEFINITION_LIGHTS,
SIMCONNECT_OBJECT_ID_USER,
SIMCONNECT_PERIOD_SIM_FRAME,
SIMCONNECT_DATA_REQUEST_FLAG_CHANGED);
end;
if Consumer.FunctionMap.HasFunction(FUNCTION_FSX_PARKINGBRAKE) then
begin
SimConnect_AddToDataDefinition(SimConnectHandle, DEFINITION_PARKINGBRAKE,
FSX_VARIABLE_PARKINGBRAKE,
FSX_UNIT_BOOL,
SIMCONNECT_DATATYPE_INT32);
SimConnect_RequestDataOnSimObject(SimConnectHandle, DEFINITION_PARKINGBRAKE,
DEFINITION_PARKINGBRAKE,
SIMCONNECT_OBJECT_ID_USER,
SIMCONNECT_PERIOD_SIM_FRAME,
SIMCONNECT_DATA_REQUEST_FLAG_CHANGED); SIMCONNECT_DATA_REQUEST_FLAG_CHANGED);
end; end;
end; end;
@ -135,6 +181,7 @@ end;
procedure TFSXLEDStateProvider.HandleDispatch(AData: PSimConnectRecv); procedure TFSXLEDStateProvider.HandleDispatch(AData: PSimConnectRecv);
var var
simObjectData: PSimConnectRecvSimObjectData; simObjectData: PSimConnectRecvSimObjectData;
states: Cardinal;
begin begin
case SIMCONNECT_RECV_ID(AData^.dwID) of case SIMCONNECT_RECV_ID(AData^.dwID) of
@ -143,7 +190,7 @@ begin
simObjectData := PSimConnectRecvSimObjectData(AData); simObjectData := PSimConnectRecvSimObjectData(AData);
case simObjectData^.dwRequestID of case simObjectData^.dwRequestID of
REQUEST_GEAR: DEFINITION_GEAR:
begin begin
case Trunc(GetDataDouble(simObjectData^.dwData) * 100) of case Trunc(GetDataDouble(simObjectData^.dwData) * 100) of
0: Consumer.SetStateByFunction(FUNCTION_FSX_GEAR, lsRed); 0: Consumer.SetStateByFunction(FUNCTION_FSX_GEAR, lsRed);
@ -151,6 +198,26 @@ begin
else Consumer.SetStateByFunction(FUNCTION_FSX_GEAR, lsAmber); else Consumer.SetStateByFunction(FUNCTION_FSX_GEAR, lsAmber);
end; end;
end; end;
DEFINITION_LIGHTS:
begin
states := simObjectData^.dwData;
if (states and FSX_LIGHTON_LANDING) <> 0 then
Consumer.SetStateByFunction(FUNCTION_FSX_LANDINGLIGHTS, lsGreen)
else
Consumer.SetStateByFunction(FUNCTION_FSX_LANDINGLIGHTS, lsRed);
if (states and FSX_LIGHTON_PANEL) <> 0 then
Consumer.SetStateByFunction(FUNCTION_FSX_INSTRUMENTLIGHTS, lsGreen)
else
Consumer.SetStateByFunction(FUNCTION_FSX_INSTRUMENTLIGHTS, lsRed);
end;
DEFINITION_PARKINGBRAKE:
if GetDataBoolean(simObjectData^.dwData) then
Consumer.SetStateByFunction(FUNCTION_FSX_PARKINGBRAKE, lsRed)
else
Consumer.SetStateByFunction(FUNCTION_FSX_PARKINGBRAKE, lsGreen);
end; end;
end; end;
@ -160,6 +227,12 @@ begin
end; end;
function TFSXLEDStateProvider.GetDataBoolean(var AData: Cardinal): Boolean;
begin
Result := (AData <> 0);
end;
function TFSXLEDStateProvider.GetDataDouble(var AData: Cardinal): Double; function TFSXLEDStateProvider.GetDataDouble(var AData: Cardinal): Double;
begin begin
Result := PDouble(@AData)^; Result := PDouble(@AData)^;

View File

@ -14,8 +14,8 @@ uses
const const
MSG_FINDTHROTTLEDEVICE = MSG_CONSUMER_OFFSET + 1; MSG_FINDTHROTTLEDEVICE = MSG_CONSUMER_OFFSET + 1;
MSG_NOTIFY_DEVICESTATE = MSG_CONSUMER_OFFSET + 2;
type type
TG940LEDStateConsumer = class(TLEDStateConsumer) TG940LEDStateConsumer = class(TLEDStateConsumer)
private private
@ -38,8 +38,6 @@ type
const const
MSG_NOTIFY_DEVICESTATE = 1;
DEVICESTATE_SEARCHING = 0; DEVICESTATE_SEARCHING = 0;
DEVICESTATE_FOUND = 1; DEVICESTATE_FOUND = 1;
DEVICESTATE_NOTFOUND = 2; DEVICESTATE_NOTFOUND = 2;
@ -56,6 +54,19 @@ uses
LogiJoystickDLL; LogiJoystickDLL;
type
TRunInMainThreadSetButtonColor = class(TInterfacedObject, IRunInMainThread)
private
FDevice: IDirectInputDevice8;
FButton: TLogiPanelButton;
FColor: TLogiColor;
protected
procedure Execute;
public
constructor Create(device: IDirectInputDevice8; button: TLogiPanelButton; color: TLogiColor);
end;
function EnumDevicesProc(var lpddi: TDIDeviceInstanceA; pvRef: Pointer): BOOL; stdcall; function EnumDevicesProc(var lpddi: TDIDeviceInstanceA; pvRef: Pointer): BOOL; stdcall;
var var
vendorID: Word; vendorID: Word;
@ -109,6 +120,7 @@ end;
procedure TG940LEDStateConsumer.LEDStateChanged(ALEDIndex: Integer; AState: TLEDState); procedure TG940LEDStateConsumer.LEDStateChanged(ALEDIndex: Integer; AState: TLEDState);
var var
color: TLogiColor; color: TLogiColor;
// msg: TMsg;
begin begin
// ToDo SetLEDs gebruiken (vereist override van SetStateByFunction om te groeperen) // ToDo SetLEDs gebruiken (vereist override van SetStateByFunction om te groeperen)
@ -127,8 +139,8 @@ begin
lsError: color := LOGI_RED; lsError: color := LOGI_RED;
end; end;
SetButtonColor(ThrottleDevice, TLogiPanelButton(ALEDIndex), color); { Logitech SDK will not change the color outside of the main thread }
ProcessMessages; RunInMainThread(TRunInMainThreadSetButtonColor.Create(ThrottleDevice, TLogiPanelButton(ALEDIndex), color));
end; end;
end; end;
@ -187,4 +199,21 @@ end;
// end; // end;
//end; //end;
{ TRunInMainThreadSetButtonColor }
constructor TRunInMainThreadSetButtonColor.Create(device: IDirectInputDevice8; button: TLogiPanelButton; color: TLogiColor);
begin
inherited Create;
FDevice := device;
FButton := button;
FColor := color;
end;
procedure TRunInMainThreadSetButtonColor.Execute;
begin
SetButtonColor(FDevice, FButton, FColor);
end;
end. end.

View File

@ -16,12 +16,21 @@ const
MSG_FINALIZE_PROVIDER = 4; MSG_FINALIZE_PROVIDER = 4;
MSG_PROCESS_MESSAGES = 5; MSG_PROCESS_MESSAGES = 5;
MSG_CONSUMER_OFFSET = MSG_PROCESS_MESSAGES; MSG_RUN_IN_MAINTHREAD = 6;
MSG_CONSUMER_OFFSET = MSG_RUN_IN_MAINTHREAD;
TIMER_PROCESSMESSAGES = 1; TIMER_PROCESSMESSAGES = 1;
type type
{ This interface name made me giggle. Because it's true. }
IRunInMainThread = interface
['{68B8F2F7-ED40-4078-9D99-503D7AFA068B}']
procedure Execute;
end;
TLEDStateConsumer = class(TOmniWorker, ILEDStateConsumer) TLEDStateConsumer = class(TOmniWorker, ILEDStateConsumer)
private private
FFunctionMap: TLEDFunctionMap; FFunctionMap: TLEDFunctionMap;
@ -38,6 +47,7 @@ type
procedure InitializeProvider(AProviderClass: TLEDStateProviderClass); procedure InitializeProvider(AProviderClass: TLEDStateProviderClass);
procedure FinalizeProvider; procedure FinalizeProvider;
procedure RunInMainThread(AExecutor: IRunInMainThread);
procedure LEDStateChanged(ALEDIndex: Integer; AState: TLEDState); virtual; procedure LEDStateChanged(ALEDIndex: Integer; AState: TLEDState); virtual;
{ ILEDStateConsumer } { ILEDStateConsumer }
@ -62,6 +72,7 @@ type
implementation implementation
uses uses
SysUtils, SysUtils,
Windows,
OtlCommon; OtlCommon;
@ -146,7 +157,7 @@ begin
FinalizeProvider; FinalizeProvider;
FProvider := AProviderClass.Create(Self); FProvider := AProviderClass.Create(Self);
// ToDo exception handlign // ToDo exception handling
Provider.Initialize; Provider.Initialize;
if Provider.ProcessMessagesInterval > -1 then if Provider.ProcessMessagesInterval > -1 then
@ -174,6 +185,12 @@ begin
end; end;
procedure TLEDStateConsumer.RunInMainThread(AExecutor: IRunInMainThread);
begin
Task.Comm.Send(MSG_RUN_IN_MAINTHREAD, AExecutor);
end;
procedure TLEDStateConsumer.LEDStateChanged(ALEDIndex: Integer; AState: TLEDState); procedure TLEDStateConsumer.LEDStateChanged(ALEDIndex: Integer; AState: TLEDState);
begin begin
end; end;