//------------------------------------------------------------------------------ // // SimConnect AI Objects sample // // Description: // Adds Non ATC controlled simulation objects. // Launch a flight from KSEA - Runway 34R // and watch the antics. // Press z to create the objects // Press x to load them with their waypoint lists // Press c to remove the generated objects //------------------------------------------------------------------------------ #include #include #include #include #include "SimConnect.h" int quit = 0; HANDLE hSimConnect = NULL; DWORD DA62ID = SIMCONNECT_OBJECT_ID_USER; static enum EVENT_ID { EVENT_SIM_START, EVENT_Z, EVENT_X, EVENT_C }; static enum DATA_REQUEST_ID { REQUEST_ADD_DA62, REQUEST_REMOVE_DA62, }; static enum GROUP_ID { GROUP_ZX, }; static enum INPUT_ID { INPUT_ZX, }; static enum DEFINITION_ID { DEFINITION_WAYPOINT }; // Set up flags so these operations only happen once static bool objectsCreated = false; void sendFlightPlans() { static bool bAlternate = true; bAlternate = !bAlternate; HRESULT hr; SIMCONNECT_DATA_WAYPOINT waypointListDA62[3]; // DA62 waypoint list // DA62 aircraft should fly in circles across the North end of the runway waypointListDA62[0].Flags = SIMCONNECT_WAYPOINT_SPEED_REQUESTED; waypointListDA62[0].Altitude = 800; waypointListDA62[0].Latitude = 0; waypointListDA62[0].Longitude = 0; waypointListDA62[0].ktsSpeed = 150; waypointListDA62[1].Flags = SIMCONNECT_WAYPOINT_SPEED_REQUESTED; waypointListDA62[1].Altitude = 600; waypointListDA62[1].Latitude = 0; waypointListDA62[1].Longitude = bAlternate? 0.1 : -0.1; waypointListDA62[1].ktsSpeed = 150; waypointListDA62[2].Flags = SIMCONNECT_WAYPOINT_SPEED_REQUESTED; waypointListDA62[2].Altitude = 1000; waypointListDA62[2].Latitude = 0.1; waypointListDA62[2].Longitude = 0.; waypointListDA62[2].ktsSpeed = 150; // Send the three waypoints to the DA62 hr = SimConnect_SetDataOnSimObject(hSimConnect, DEFINITION_WAYPOINT, DA62ID, 0, bAlternate ? 2 : 3, sizeof(waypointListDA62[0]), waypointListDA62); } void setUpSimObjects() { SIMCONNECT_DATA_INITPOSITION Init; HRESULT hr; // Initialize DA62 aircraft Init.Altitude = 1000.0; Init.Latitude = -0.1; Init.Longitude = 0.; Init.Pitch = 0.0; Init.Bank = 0.0; Init.Heading = 0; Init.OnGround = 1; Init.Airspeed = 0; hr = SimConnect_AICreateNonATCAircraft(hSimConnect, "DA62 Asobo", "N1001", Init, REQUEST_ADD_DA62); } void removeSimObjects() { HRESULT hr; if (DA62ID != SIMCONNECT_OBJECT_ID_USER) { hr = SimConnect_AIRemoveObject(hSimConnect, DA62ID, REQUEST_REMOVE_DA62); } } static const char* ExceptionName(SIMCONNECT_EXCEPTION exception) { switch (exception) { case SIMCONNECT_EXCEPTION_NONE: //0 return "EXCEPTION_NONE (0)"; case SIMCONNECT_EXCEPTION_ERROR: //1 return "EXCEPTION_ERROR (1)"; case SIMCONNECT_EXCEPTION_SIZE_MISMATCH: //2 return "EXCEPTION_SIZE_MISMATCH (2)"; case SIMCONNECT_EXCEPTION_UNRECOGNIZED_ID: //3 return "EXCEPTION_UNRECOGNIZED_ID (3)"; case SIMCONNECT_EXCEPTION_UNOPENED: //4 return "EXCEPTION_UNOPENED (4)"; case SIMCONNECT_EXCEPTION_VERSION_MISMATCH: //5 return "EXCEPTION_VERSION_MISMATCH (5)"; case SIMCONNECT_EXCEPTION_TOO_MANY_GROUPS: //6 return "EXCEPTION_TOO_MANY_GROUPS (6)"; case SIMCONNECT_EXCEPTION_NAME_UNRECOGNIZED://7 return "EXCEPTION_NAME_UNRECOGNIZED (7)"; case SIMCONNECT_EXCEPTION_TOO_MANY_EVENT_NAMES: //8 return "EXCEPTION_TOO_MANY_EVENT_NAMES (8)"; case SIMCONNECT_EXCEPTION_EVENT_ID_DUPLICATE: //9 return "EXCEPTION_EVENT_ID_DUPLICATE (9)"; case SIMCONNECT_EXCEPTION_TOO_MANY_MAPS: //10 return "EXCEPTION_TOO_MANY_MAPS (10)"; case SIMCONNECT_EXCEPTION_TOO_MANY_OBJECTS: //11 return "EXCEPTION_TOO_MANY_OBJECTS (11)"; case SIMCONNECT_EXCEPTION_TOO_MANY_REQUESTS: //12 return "EXCEPTION_TOO_MANY_REQUESTS (12)"; case SIMCONNECT_EXCEPTION_WEATHER_INVALID_PORT: //13 return "EXCEPTION_WEATHER_INVALID_PORT (13)"; case SIMCONNECT_EXCEPTION_WEATHER_INVALID_METAR: //14 return "EXCEPTION_WEATHER_INVALID_METAR (14)"; case SIMCONNECT_EXCEPTION_WEATHER_UNABLE_TO_GET_OBSERVATION://15 return "EXCEPTION_WEATHER_UNABLE_TO_GET_OBSERVATION (15)"; case SIMCONNECT_EXCEPTION_WEATHER_UNABLE_TO_CREATE_STATION: //16 return "EXCEPTION_WEATHER_UNABLE_TO_CREATE_STATION (16)"; case SIMCONNECT_EXCEPTION_WEATHER_UNABLE_TO_REMOVE_STATION: //17 return "EXCEPTION_WEATHER_UNABLE_TO_REMOVE_STATION (17)"; case SIMCONNECT_EXCEPTION_INVALID_DATA_TYPE: //18 return "EXCEPTION_INVALID_DATA_TYPE (18)"; case SIMCONNECT_EXCEPTION_INVALID_DATA_SIZE: //19 return "EXCEPTION_INVALID_DATA_SIZE (19)"; case SIMCONNECT_EXCEPTION_DATA_ERROR: //20 return "EXCEPTION_DATA_ERROR (20)"; case SIMCONNECT_EXCEPTION_INVALID_ARRAY: //21 return "EXCEPTION_INVALID_ARRAY (21)"; case SIMCONNECT_EXCEPTION_CREATE_OBJECT_FAILED: //22 return "EXCEPTION_CREATE_OBJECT_FAILED (22)"; case SIMCONNECT_EXCEPTION_LOAD_FLIGHTPLAN_FAILED: //23 return "EXCEPTION_LOAD_FLIGHTPLAN_FAILED (23)"; case SIMCONNECT_EXCEPTION_OPERATION_INVALID_FOR_OBJECT_TYPE://24 return "EXCEPTION_OPERATION_INVALID_FOR_OBJECT_TYPE (24)"; case SIMCONNECT_EXCEPTION_ILLEGAL_OPERATION: //25 return "EXCEPTION_ILLEGAL_OPERATION (25)"; case SIMCONNECT_EXCEPTION_ALREADY_SUBSCRIBED: //26 return "EXCEPTION_ALREADY_SUBSCRIBED (26)"; case SIMCONNECT_EXCEPTION_INVALID_ENUM: //27 return "EXCEPTION_INVALID_ENUM (27)"; case SIMCONNECT_EXCEPTION_DEFINITION_ERROR: //28 return "EXCEPTION_DEFINITION_ERROR (28)"; case SIMCONNECT_EXCEPTION_DUPLICATE_ID: //29 return "EXCEPTION_DUPLICATE_ID (29)"; case SIMCONNECT_EXCEPTION_DATUM_ID: //30 return "EXCEPTION_DATUM_ID (30)"; case SIMCONNECT_EXCEPTION_OUT_OF_BOUNDS: //31 return "EXCEPTION_OUT_OF_BOUNDS (31)"; case SIMCONNECT_EXCEPTION_ALREADY_CREATED: //32 return "EXCEPTION_ALREADY_CREATED (32)"; case SIMCONNECT_EXCEPTION_OBJECT_OUTSIDE_REALITY_BUBBLE://33 return "EXCEPTION_OBJECT_OUTSIDE_REALITY_BUBBLE (33)"; case SIMCONNECT_EXCEPTION_OBJECT_CONTAINER: //34 return "EXCEPTION_OBJECT_CONTAINER (34)"; case SIMCONNECT_EXCEPTION_OBJECT_AI: //35 return "EXCEPTION_OBJECT_AI (35)"; case SIMCONNECT_EXCEPTION_OBJECT_ATC: //36 return "EXCEPTION_OBJECT_ATC (36)"; case SIMCONNECT_EXCEPTION_OBJECT_SCHEDULE: //37 return "EXCEPTION_OBJECT_SCHEDULE (37)"; default: return "UNKNOWN EXCEPTION"; } } void CALLBACK MyDispatchProcSO(SIMCONNECT_RECV* pData, DWORD cbData, void* pContext) { HRESULT hr; switch (pData->dwID) { case SIMCONNECT_RECV_ID_EVENT: { SIMCONNECT_RECV_EVENT* evt = (SIMCONNECT_RECV_EVENT*)pData; switch (evt->uEventID) { case EVENT_Z: if (!objectsCreated) { setUpSimObjects(); objectsCreated = true; printf("\nPress 'x' to change the flight plans"); } break; case EVENT_X: if (objectsCreated) { sendFlightPlans(); } break; case EVENT_C: if (objectsCreated) { removeSimObjects(); objectsCreated = false; } break; default: printf("\nUnknown event: %d", evt->uEventID); break; } break; } case SIMCONNECT_RECV_ID_ASSIGNED_OBJECT_ID: { SIMCONNECT_RECV_ASSIGNED_OBJECT_ID* pObjData = (SIMCONNECT_RECV_ASSIGNED_OBJECT_ID*)pData; switch (pObjData->dwRequestID) { case REQUEST_ADD_DA62: DA62ID = pObjData->dwObjectID; printf("\nCreated DA62 id = %d", DA62ID); break; default: printf("\nUnknown creation %d", pObjData->dwRequestID); break; } break; } case SIMCONNECT_RECV_ID_QUIT: { quit = 1; break; } case SIMCONNECT_RECV_ID_EXCEPTION: { SIMCONNECT_RECV_EXCEPTION* data = (SIMCONNECT_RECV_EXCEPTION*)(pData); SIMCONNECT_EXCEPTION exception = (SIMCONNECT_EXCEPTION)(data->dwException); printf("\nException: %s", ExceptionName(exception)); break; } default: printf("\nReceived:%d", pData->dwID); break; } } void testSimObjects() { HRESULT hr; if (SUCCEEDED(SimConnect_Open(&hSimConnect, "AI Objects and Waypoints", NULL, 0, 0, 0))) { printf("\nConnected to Flight Simulator!"); // Create some private events hr = SimConnect_MapClientEventToSimEvent(hSimConnect, EVENT_Z); hr = SimConnect_MapClientEventToSimEvent(hSimConnect, EVENT_X); hr = SimConnect_MapClientEventToSimEvent(hSimConnect, EVENT_C); // Link the private events to keyboard keys, and ensure the input events are off hr = SimConnect_MapInputEventToClientEvent(hSimConnect, INPUT_ZX, "Z", EVENT_Z); hr = SimConnect_MapInputEventToClientEvent(hSimConnect, INPUT_ZX, "X", EVENT_X); hr = SimConnect_MapInputEventToClientEvent(hSimConnect, INPUT_ZX, "C", EVENT_C); hr = SimConnect_SetInputGroupState(hSimConnect, INPUT_ZX, SIMCONNECT_STATE_OFF); // Sign up for notifications hr = SimConnect_AddClientEventToNotificationGroup(hSimConnect, GROUP_ZX, EVENT_Z); hr = SimConnect_AddClientEventToNotificationGroup(hSimConnect, GROUP_ZX, EVENT_X); hr = SimConnect_AddClientEventToNotificationGroup(hSimConnect, GROUP_ZX, EVENT_C); // Set up a definition for a waypoint list hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_WAYPOINT, "AI Waypoint List", "number", SIMCONNECT_DATATYPE_WAYPOINT); hr = SimConnect_SetInputGroupState(hSimConnect, INPUT_ZX, SIMCONNECT_STATE_ON); printf("\nPress 'z' to create the aircrafts"); printf("\nLaunch a flight."); while (0 == quit) { SimConnect_CallDispatch(hSimConnect, MyDispatchProcSO, NULL); Sleep(1); } hr = SimConnect_Close(hSimConnect); } } int __cdecl _tmain(int argc, _TCHAR* argv[]) { testSimObjects(); return 0; }