Guest User

Untitled

a guest
Dec 16th, 2012
370
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.95 KB | None | 0 0
  1. //------------------------------------------------------------------------------
  2. //
  3. //  PMDG 737NGX external connection sample
  4. //
  5. //------------------------------------------------------------------------------
  6.  
  7. #include "PMDG_NGX_SDK.h"
  8.  
  9. #include <windows.h>
  10. #include <tchar.h>
  11. #include <stdio.h>
  12. #include <strsafe.h>
  13.  
  14. #include "SimConnect.h"
  15.  
  16. int     quit = 0;
  17. HANDLE  hSimConnect = NULL;
  18. bool    AircraftRunning = false;       
  19. PMDG_NGX_Control Control;
  20.  
  21.  
  22. static enum DATA_REQUEST_ID {
  23.     DATA_REQUEST,
  24.     CONTROL_REQUEST,
  25.     AIR_PATH_REQUEST
  26. };
  27.  
  28. static enum EVENT_ID {
  29.     EVENT_SIM_START,    // used to track the loaded aircraft
  30.  
  31.     EVENT_LOGO_LIGHT_SWITCH,
  32.     EVENT_FLIGHT_DIRECTOR_SWITCH,
  33.     EVENT_HEADING_SELECTOR,
  34.  
  35.     EVENT_KEYBOARD_A,
  36.     EVENT_KEYBOARD_B,
  37.     EVENT_KEYBOARD_C,
  38.     EVENT_KEYBOARD_D
  39. };
  40.  
  41. static enum INPUT_ID {
  42.     INPUT0          // used to handle key presses
  43. };
  44.  
  45. static enum GROUP_ID {
  46.     GROUP_KEYBOARD      // used to handle key presses
  47. };
  48.  
  49.  
  50. // this variable keeps the state of one of the NGX switches
  51. // NOTE - add these lines to <FSX>\PMDG\PMDG 737 NGX\737NGX_Options.ini:
  52. //
  53. //[SDK]
  54. //EnableDataBroadcast=1
  55. //
  56. // to enable the data sending from the NGX.
  57.  
  58. bool NGX_FuelPumpLAftLight = true;
  59. bool NGX_TaxiLightSwitch = false;
  60. bool NGX_LogoLightSwitch = false;
  61.  
  62. // This function is called when NGX data changes
  63. void ProcessNGXData (PMDG_NGX_Data *pS)
  64. {
  65.     // test the data access:
  66.     // get the state of an annunciator light and display it
  67.     if (pS->FUEL_annunLOWPRESS_Aft[0] != NGX_FuelPumpLAftLight)
  68.     {
  69.         NGX_FuelPumpLAftLight = pS->FUEL_annunLOWPRESS_Aft[0];
  70.         if (NGX_FuelPumpLAftLight)
  71.             printf("\nLOW PRESS LIGHT: [ON]");
  72.         else
  73.             printf("\nLOW PRESS LIGHT: [OFF]");
  74.     }
  75.  
  76.     // get the state of switches and save it for later use
  77.     if (pS->LTS_TaxiSw != NGX_TaxiLightSwitch)
  78.     {
  79.         NGX_TaxiLightSwitch = pS->LTS_TaxiSw;
  80.         if (NGX_TaxiLightSwitch)
  81.             printf("\nTAXI LIGHTS: [ON]");
  82.         else
  83.             printf("\nTAXI LIGHTS: [OFF]");
  84.     }
  85.  
  86.     if (pS->LTS_LogoSw != NGX_LogoLightSwitch)
  87.     {
  88.         NGX_LogoLightSwitch = pS->LTS_LogoSw;
  89.         if (NGX_LogoLightSwitch)
  90.             printf("\nLOGO LIGHTS: [ON]");
  91.         else
  92.             printf("\nLOGO LIGHTS: [OFF]");
  93.     }
  94. }
  95.  
  96. void toggleTaxiLightSwitch()
  97. {
  98.     // Test the first control method: use the control data area.
  99.     if (AircraftRunning)
  100.     {
  101.         bool New_TaxiLightSwitch = !NGX_TaxiLightSwitch;
  102.  
  103.         // Send a command only if there is no active command request and previous command has been processed by the NGX
  104.         if (Control.Event == 0)
  105.         {
  106.             Control.Event = EVT_OH_LIGHTS_TAXI;     // = 69749
  107.             if (New_TaxiLightSwitch)
  108.                 Control.Parameter = 1;
  109.             else
  110.                 Control.Parameter = 0;
  111.             SimConnect_SetClientData (hSimConnect, PMDG_NGX_CONTROL_ID, PMDG_NGX_CONTROL_DEFINITION,
  112.                 0, 0, sizeof(PMDG_NGX_Control), &Control);
  113.         }
  114.     }
  115. }
  116.  
  117. void toggleLogoLightsSwitch()
  118. {
  119.     // Test the second control method: send an event
  120.     // use direct switch position
  121.     bool New_LogoLightSwitch = !NGX_LogoLightSwitch;
  122.  
  123.     int parameter = New_LogoLightSwitch? 1 : 0;
  124.     SimConnect_TransmitClientEvent(hSimConnect, 0, EVENT_LOGO_LIGHT_SWITCH, parameter,
  125.             SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
  126. }
  127.  
  128. void toggleFlightDirector()
  129. {
  130.     // Test the second control method: send an event
  131.     // use mouse simulation to toggle the switch
  132.     SimConnect_TransmitClientEvent(hSimConnect, 0, EVENT_FLIGHT_DIRECTOR_SWITCH, MOUSE_FLAG_LEFTSINGLE,
  133.         SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
  134.     SimConnect_TransmitClientEvent(hSimConnect, 0, EVENT_FLIGHT_DIRECTOR_SWITCH, MOUSE_FLAG_LEFTRELEASE,
  135.         SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
  136. }
  137.  
  138. void slewHeadingSelector()
  139. {
  140.     // Test the second control method: send an event
  141.     // use mouse simulation to slew a knob
  142.     SimConnect_TransmitClientEvent(hSimConnect, 0, EVENT_HEADING_SELECTOR, MOUSE_FLAG_WHEEL_UP,
  143.         SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
  144. }
  145.  
  146. void CALLBACK MyDispatchProc(SIMCONNECT_RECV* pData, DWORD cbData, void *pContext)
  147. {
  148.     switch(pData->dwID)
  149.     {
  150.     case SIMCONNECT_RECV_ID_CLIENT_DATA: // Receive and process the NGX data block
  151.         {
  152.             SIMCONNECT_RECV_CLIENT_DATA *pObjData = (SIMCONNECT_RECV_CLIENT_DATA*)pData;
  153.  
  154.             switch(pObjData->dwRequestID)
  155.             {
  156.             case DATA_REQUEST:
  157.                 {
  158.                     PMDG_NGX_Data *pS = (PMDG_NGX_Data*)&pObjData->dwData;
  159.                     ProcessNGXData(pS);
  160.                     break;
  161.                 }
  162.             case CONTROL_REQUEST:
  163.                 {
  164.                     // keep the present state of Control area to know if the server had received and reset the command
  165.                     PMDG_NGX_Control *pS = (PMDG_NGX_Control*)&pObjData->dwData;
  166.                     Control = *pS;
  167.                     break;
  168.                 }
  169.             }
  170.             break;
  171.         }
  172.  
  173.     case SIMCONNECT_RECV_ID_EVENT: 
  174.         {
  175.             SIMCONNECT_RECV_EVENT *evt = (SIMCONNECT_RECV_EVENT*)pData;
  176.             switch (evt->uEventID)
  177.             {
  178.             case EVENT_SIM_START:   // Track aircraft changes
  179.                 {
  180.                     HRESULT hr = SimConnect_RequestSystemState(hSimConnect, AIR_PATH_REQUEST, "AircraftLoaded");
  181.                     break;
  182.                 }
  183.             case EVENT_KEYBOARD_A:
  184.                 {
  185.                     toggleTaxiLightSwitch();
  186.                     break;
  187.                 }
  188.             case EVENT_KEYBOARD_B:
  189.                 {
  190.                     toggleLogoLightsSwitch();
  191.                     break;
  192.                 }
  193.             case EVENT_KEYBOARD_C:
  194.                 {
  195.                     toggleFlightDirector();
  196.                     break;
  197.                 }
  198.             case EVENT_KEYBOARD_D:
  199.                 {
  200.                     slewHeadingSelector();
  201.                     break;
  202.                 }
  203.             }
  204.             break;
  205.         }
  206.  
  207.     case SIMCONNECT_RECV_ID_SYSTEM_STATE: // Track aircraft changes
  208.         {
  209.             SIMCONNECT_RECV_SYSTEM_STATE *evt = (SIMCONNECT_RECV_SYSTEM_STATE*)pData;
  210.             if (evt->dwRequestID == AIR_PATH_REQUEST)
  211.             {
  212.                 if (strstr(evt->szString, "PMDG 737") != NULL)
  213.                     AircraftRunning = true;
  214.                 else
  215.                     AircraftRunning = false;
  216.             }
  217.             break;
  218.         }
  219.  
  220.     case SIMCONNECT_RECV_ID_QUIT:
  221.         {
  222.             quit = 1;
  223.             break;
  224.         }
  225.  
  226.     default:
  227.         printf("\nReceived:%d",pData->dwID);
  228.         break;
  229.     }
  230. }
  231.  
  232. void testCommunication()
  233. {
  234.     HRESULT hr;
  235.  
  236.     if (SUCCEEDED(SimConnect_Open(&hSimConnect, "PMDG NGX Test", NULL, 0, 0, 0)))
  237.     {
  238.         printf("\nConnected to Flight Simulator!");  
  239.        
  240.         // 1) Set up data connection
  241.  
  242.         // Associate an ID with the PMDG data area name
  243.         hr = SimConnect_MapClientDataNameToID (hSimConnect, PMDG_NGX_DATA_NAME, PMDG_NGX_DATA_ID);
  244.  
  245.         // Define the data area structure - this is a required step
  246.         hr = SimConnect_AddToClientDataDefinition (hSimConnect, PMDG_NGX_DATA_DEFINITION, 0, sizeof(PMDG_NGX_Data), 0, 0);
  247.  
  248.         // Sign up for notification of data change.  
  249.         // SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_CHANGED flag asks for the data to be sent only when some of the data is changed.
  250.         hr = SimConnect_RequestClientData(hSimConnect, PMDG_NGX_DATA_ID, DATA_REQUEST, PMDG_NGX_DATA_DEFINITION,
  251.                                                        SIMCONNECT_CLIENT_DATA_PERIOD_ON_SET, SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_CHANGED, 0, 0, 0);
  252.  
  253.        
  254.         // 2) Set up control connection
  255.  
  256.         // First method: control data area
  257.         Control.Event = 0;
  258.         Control.Parameter = 0;
  259.  
  260.         // Associate an ID with the PMDG control area name
  261.         hr = SimConnect_MapClientDataNameToID (hSimConnect, PMDG_NGX_CONTROL_NAME, PMDG_NGX_CONTROL_ID);
  262.  
  263.         // Define the control area structure - this is a required step
  264.         hr = SimConnect_AddToClientDataDefinition (hSimConnect, PMDG_NGX_CONTROL_DEFINITION, 0, sizeof(PMDG_NGX_Control), 0, 0);
  265.        
  266.         // Sign up for notification of control change.  
  267.         hr = SimConnect_RequestClientData(hSimConnect, PMDG_NGX_CONTROL_ID, CONTROL_REQUEST, PMDG_NGX_CONTROL_DEFINITION,
  268.             SIMCONNECT_CLIENT_DATA_PERIOD_ON_SET, SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_CHANGED, 0, 0, 0);
  269.  
  270.         // Second method: Create event IDs for controls that we are going to operate
  271.         hr = SimConnect_MapClientEventToSimEvent(hSimConnect, EVENT_LOGO_LIGHT_SWITCH, "#69754");       //EVT_OH_LIGHTS_LOGO
  272.         hr = SimConnect_MapClientEventToSimEvent(hSimConnect, EVENT_FLIGHT_DIRECTOR_SWITCH, "#70010");  //EVT_MCP_FD_SWITCH_L
  273.         hr = SimConnect_MapClientEventToSimEvent(hSimConnect, EVENT_HEADING_SELECTOR, "#70022");        //EVT_MCP_HEADING_SELECTOR
  274.  
  275.  
  276.         // 3) Request current aircraft .air file path
  277.         hr = SimConnect_RequestSystemState(hSimConnect, AIR_PATH_REQUEST, "AircraftLoaded");
  278.         // also request notifications on sim start and aircraft change
  279.         hr = SimConnect_SubscribeToSystemEvent(hSimConnect, EVENT_SIM_START, "SimStart");
  280.  
  281.  
  282.         // 4) Assign keyboard shortcuts
  283.         hr = SimConnect_MapClientEventToSimEvent(hSimConnect, EVENT_KEYBOARD_A);
  284.         hr = SimConnect_MapClientEventToSimEvent(hSimConnect, EVENT_KEYBOARD_B);
  285.         hr = SimConnect_MapClientEventToSimEvent(hSimConnect, EVENT_KEYBOARD_C);
  286.         hr = SimConnect_MapClientEventToSimEvent(hSimConnect, EVENT_KEYBOARD_D);
  287.  
  288.         hr = SimConnect_AddClientEventToNotificationGroup(hSimConnect, GROUP_KEYBOARD, EVENT_KEYBOARD_A);
  289.         hr = SimConnect_AddClientEventToNotificationGroup(hSimConnect, GROUP_KEYBOARD, EVENT_KEYBOARD_B);
  290.         hr = SimConnect_AddClientEventToNotificationGroup(hSimConnect, GROUP_KEYBOARD, EVENT_KEYBOARD_C);
  291.         hr = SimConnect_AddClientEventToNotificationGroup(hSimConnect, GROUP_KEYBOARD, EVENT_KEYBOARD_D);
  292.  
  293.         hr = SimConnect_SetNotificationGroupPriority(hSimConnect, GROUP_KEYBOARD, SIMCONNECT_GROUP_PRIORITY_HIGHEST);
  294.  
  295.         hr = SimConnect_MapInputEventToClientEvent(hSimConnect, INPUT0, "shift+ctrl+a", EVENT_KEYBOARD_A);
  296.         hr = SimConnect_MapInputEventToClientEvent(hSimConnect, INPUT0, "shift+ctrl+b", EVENT_KEYBOARD_B);
  297.         hr = SimConnect_MapInputEventToClientEvent(hSimConnect, INPUT0, "shift+ctrl+c", EVENT_KEYBOARD_C);
  298.         hr = SimConnect_MapInputEventToClientEvent(hSimConnect, INPUT0, "shift+ctrl+d", EVENT_KEYBOARD_D);
  299.  
  300.         hr = SimConnect_SetInputGroupState(hSimConnect, INPUT0, SIMCONNECT_STATE_ON);
  301.  
  302.  
  303.         // 5) Main loop
  304.         while( quit == 0 )
  305.         {
  306.             // receive and process the NGX data
  307.             SimConnect_CallDispatch(hSimConnect, MyDispatchProc, NULL);
  308.  
  309.             Sleep(1);
  310.         }
  311.  
  312.         hr = SimConnect_Close(hSimConnect);
  313.     }
  314.     else
  315.         printf("\nUnable to connect!\n");
  316. }
  317.  
  318. int __cdecl _tmain(int argc, _TCHAR* argv[])
  319. {
  320.  
  321.     testCommunication();
  322.  
  323.     return 0;
  324. }
Advertisement
Add Comment
Please, Sign In to add comment