1
0
mirror of synced 2024-06-25 22:57:40 +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
ItemIndex = 0
TabOrder = 1
Text = '<Not assigned>'
Text = 'Parking brake'
Items.Strings = (
'<Not assigned>')
'Parking brake')
end
object cmbFSXP3: TComboBox
Left = 69
@ -152,9 +152,9 @@ object MainForm: TMainForm
ItemHeight = 13
ItemIndex = 0
TabOrder = 2
Text = '<Not assigned>'
Text = 'Landing lights'
Items.Strings = (
'<Not assigned>')
'Landing lights')
end
object cmbFSXP4: TComboBox
Left = 69
@ -212,9 +212,9 @@ object MainForm: TMainForm
ItemHeight = 13
ItemIndex = 0
TabOrder = 6
Text = '<Not assigned>'
Text = 'Instrument lights'
Items.Strings = (
'<Not assigned>')
'Instrument lights')
end
object cmbFSXP8: TComboBox
Left = 69

View File

@ -77,6 +77,7 @@ type
procedure EventMonitorMessage(const task: IOmniTaskControl; const msg: TOmniMessage);
procedure HandleDeviceStateMessage(ATask: IOmniTaskControl; AMessage: TOmniMessage);
procedure HandleRunInMainThreadMessage(ATask: IOmniTaskControl; AMessage: TOmniMessage);
property EventMonitor: TOmniEventMonitor read FEventMonitor;
property StateConsumerTask: IOmniTaskControl read FStateConsumerTask;
@ -133,6 +134,7 @@ begin
FinalizeStateProvider;
StateConsumerTask.Terminate;
StateConsumerTask.WaitFor(INFINITE);
FStateConsumerTask := nil;
end;
@ -221,14 +223,18 @@ end;
procedure TMainForm.UpdateMappingFSX;
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, 6, FUNCTION_FSX_INSTRUMENTLIGHTS);
end;
procedure TMainForm.EventMonitorMessage(const task: IOmniTaskControl; const msg: TOmniMessage);
begin
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;
@ -251,6 +257,12 @@ begin
end;
procedure TMainForm.HandleRunInMainThreadMessage(ATask: IOmniTaskControl; AMessage: TOmniMessage);
begin
(AMessage.MsgData.AsInterface as IRunInMainThread).Execute;
end;
procedure TMainForm.btnFSXConnectClick(Sender: TObject);
begin
InitializeStateProvider(TFSXLEDStateProvider);

View File

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

View File

@ -14,8 +14,8 @@ uses
const
MSG_FINDTHROTTLEDEVICE = MSG_CONSUMER_OFFSET + 1;
MSG_NOTIFY_DEVICESTATE = MSG_CONSUMER_OFFSET + 2;
type
TG940LEDStateConsumer = class(TLEDStateConsumer)
private
@ -38,8 +38,6 @@ type
const
MSG_NOTIFY_DEVICESTATE = 1;
DEVICESTATE_SEARCHING = 0;
DEVICESTATE_FOUND = 1;
DEVICESTATE_NOTFOUND = 2;
@ -56,6 +54,19 @@ uses
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;
var
vendorID: Word;
@ -109,6 +120,7 @@ end;
procedure TG940LEDStateConsumer.LEDStateChanged(ALEDIndex: Integer; AState: TLEDState);
var
color: TLogiColor;
// msg: TMsg;
begin
// ToDo SetLEDs gebruiken (vereist override van SetStateByFunction om te groeperen)
@ -127,8 +139,8 @@ begin
lsError: color := LOGI_RED;
end;
SetButtonColor(ThrottleDevice, TLogiPanelButton(ALEDIndex), color);
ProcessMessages;
{ Logitech SDK will not change the color outside of the main thread }
RunInMainThread(TRunInMainThreadSetButtonColor.Create(ThrottleDevice, TLogiPanelButton(ALEDIndex), color));
end;
end;
@ -187,4 +199,21 @@ 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.

View File

@ -16,12 +16,21 @@ const
MSG_FINALIZE_PROVIDER = 4;
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;
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)
private
FFunctionMap: TLEDFunctionMap;
@ -38,6 +47,7 @@ type
procedure InitializeProvider(AProviderClass: TLEDStateProviderClass);
procedure FinalizeProvider;
procedure RunInMainThread(AExecutor: IRunInMainThread);
procedure LEDStateChanged(ALEDIndex: Integer; AState: TLEDState); virtual;
{ ILEDStateConsumer }
@ -62,6 +72,7 @@ type
implementation
uses
SysUtils,
Windows,
OtlCommon;
@ -146,7 +157,7 @@ begin
FinalizeProvider;
FProvider := AProviderClass.Create(Self);
// ToDo exception handlign
// ToDo exception handling
Provider.Initialize;
if Provider.ProcessMessagesInterval > -1 then
@ -174,6 +185,12 @@ begin
end;
procedure TLEDStateConsumer.RunInMainThread(AExecutor: IRunInMainThread);
begin
Task.Comm.Send(MSG_RUN_IN_MAINTHREAD, AExecutor);
end;
procedure TLEDStateConsumer.LEDStateChanged(ALEDIndex: Integer; AState: TLEDState);
begin
end;