diff --git a/Cargo.lock b/Cargo.lock index 7ee65d1..e42146b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -33,9 +33,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "2.11.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" [[package]] name = "cexpr" @@ -65,9 +65,9 @@ dependencies = [ [[package]] name = "either" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" [[package]] name = "glob" @@ -102,15 +102,15 @@ dependencies = [ [[package]] name = "log" -version = "0.4.29" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" [[package]] name = "memchr" -version = "2.8.0" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" [[package]] name = "minimal-lexical" @@ -149,18 +149,18 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.45" +version = "1.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" dependencies = [ "proc-macro2", ] [[package]] name = "regex" -version = "1.12.3" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +checksum = "2a0e75113e14dc5acb068cd0786884f214f1312650a3d36d269f5c4f3cdee8a2" dependencies = [ "aho-corasick", "memchr", @@ -170,9 +170,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +checksum = "1f388202e4b80542a0921078cc23b6333bcf1409c1e3f86404cae4766a6131db" dependencies = [ "aho-corasick", "memchr", @@ -181,15 +181,15 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" [[package]] name = "rustc-hash" -version = "2.1.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" [[package]] name = "shlex" @@ -199,16 +199,31 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "simconnect" -version = "0.4.0" +version = "0.5.0" +dependencies = [ + "simconnect-fs2020", + "simconnect-fs2024", +] + +[[package]] +name = "simconnect-fs2020" +version = "0.5.0" +dependencies = [ + "bindgen", +] + +[[package]] +name = "simconnect-fs2024" +version = "0.5.0" dependencies = [ "bindgen", ] [[package]] name = "syn" -version = "2.0.117" +version = "2.0.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index a0b921b..89ba20a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,21 +2,16 @@ name = "simconnect" license = "MIT" description = "Rust bindings for SimConnect" -version = "0.4.0" +version = "0.5.0" authors = ["Connor T"] -edition = "2018" +edition = "2021" -[[example]] -name = "aircraft_updates_on_change" -path = "examples/aircraft_updates_on_change/main.rs" +[dependencies] +simconnect-fs2020 = { path = "simulators/FS2020", optional = true } +simconnect-fs2024 = { path = "simulators/FS2024", optional = true } -[[example]] -name = "aircraft_updates" -path = "examples/aircraft_updates/main.rs" - -[[example]] -name = "aircraft_inputs" -path = "examples/aircraft_inputs/main.rs" - -[build-dependencies] -bindgen = "0.72" +[features] +default = ["all"] +fs2020 = ["dep:simconnect-fs2020"] +fs2024 = ["dep:simconnect-fs2024"] +all = ["fs2020", "fs2024"] diff --git a/Readme.md b/Readme.md index c960e92..70d97c7 100644 --- a/Readme.md +++ b/Readme.md @@ -2,10 +2,18 @@ # SimConnect Bindings for Rust +Send and receive information through SimConnect, for Microsoft Flight Simulator (2020). + +Documentation can be found at: [MSFS 2020 SDK](https://docs.flightsimulator.com/html/Programming_Tools/SimConnect/SimConnect_SDK.htm) + + ## Requirements -- [CLang](https://clang.llvm.org/get_started.html) (See the [Rust Bindgen Documentation](https://rust-lang.github.io/rust-bindgen/requirements.html)) -- MSVC x64 Rust build (`x86_64-pc-windows-msvc`, see [The rustup book](https://rust-lang.github.io/rustup/installation/windows.html)) +- [Rust](https://rust-lang.org/learn/get-started) +- [LLVM/Clang](https://clang.llvm.org/get_started.html) + +See the [Rust Bindgen Documentation](https://rust-lang.github.io/rust-bindgen/introduction.html) + ## Using @@ -16,14 +24,18 @@ Add this to your `Cargo.toml` simconnect = "0.4" ``` +_You must have SimConnect.dll in the same directory as your executable._ + + ## Building _The SimConnect binaries are included within this repository, but they may not be up-to-date._ -1. run `cargo build` -2. Add `use simconnect` at the top of your file +1. Run `cargo build` +2. Add import `use simconnect` at the top of your file + -## Example +## Examples Read float position data @@ -31,14 +43,13 @@ Read float position data cargo run --example aircraft_updates ``` -Requests tagged data with thresholds from SimConnect and reads floats/strings +Requests tagged data with thresholds from SimConnect, and reads floats/strings ``` cargo run --example aircraft_updates_on_change ``` -_You must have SimConnect.dll in the same directory as the compiled exe for it to run (e.g. in )_ -### Remarks +## Remarks -I have not tested every single function from the api. If you find an error, feel free to make an issue or a pull request. +I have not tested every function of the API. If you find an error, feel free to make an issue or pull request. diff --git a/build.rs b/build.rs deleted file mode 100644 index 5973c70..0000000 --- a/build.rs +++ /dev/null @@ -1,270 +0,0 @@ -use std::{env, path::PathBuf}; - -fn main() { - println!("cargo:rustc-link-search=libsrc/lib"); - println!("cargo:rustc-link-lib=static=SimConnect"); - - let bindings = bindgen::Builder::default() - .header("libsrc/include/SimConnect.hpp") - .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) - - // ==================== CONSTANTS ==================== - .allowlist_var("SIMCONNECT_UNUSED") - .allowlist_var("SIMCONNECT_OBJECT_ID_USER") - .allowlist_var("SIMCONNECT_CAMERA_IGNORE_FIELD") - .allowlist_var("SIMCONNECT_CLIENTDATA_MAX_SIZE") - .allowlist_var("SIMCONNECT_GROUP_PRIORITY_HIGHEST") - .allowlist_var("SIMCONNECT_GROUP_PRIORITY_HIGHEST_MASKABLE") - .allowlist_var("SIMCONNECT_GROUP_PRIORITY_STANDARD") - .allowlist_var("SIMCONNECT_GROUP_PRIORITY_DEFAULT") - .allowlist_var("SIMCONNECT_GROUP_PRIORITY_LOWEST") - .allowlist_var("MAX_METAR_LENGTH") - .allowlist_var("MAX_THERMAL_SIZE") - .allowlist_var("MAX_THERMAL_RATE") - .allowlist_var("INITPOSITION_AIRSPEED_CRUISE") - .allowlist_var("INITPOSITION_AIRSPEED_KEEP") - .allowlist_var("SIMCONNECT_CLIENTDATATYPE_INT8") - .allowlist_var("SIMCONNECT_CLIENTDATATYPE_INT16") - .allowlist_var("SIMCONNECT_CLIENTDATATYPE_INT32") - .allowlist_var("SIMCONNECT_CLIENTDATATYPE_INT64") - .allowlist_var("SIMCONNECT_CLIENTDATATYPE_FLOAT32") - .allowlist_var("SIMCONNECT_CLIENTDATATYPE_FLOAT64") - .allowlist_var("SIMCONNECT_CLIENTDATAOFFSET_AUTO") - .allowlist_var("SIMCONNECT_OPEN_CONFIGINDEX_LOCAL") - .allowlist_var("SIMCONNECT_RECV_ID_VOR_LIST_HAS_NAV_SIGNAL") - .allowlist_var("SIMCONNECT_RECV_ID_VOR_LIST_HAS_LOCALIZER") - .allowlist_var("SIMCONNECT_RECV_ID_VOR_LIST_HAS_GLIDE_SLOPE") - .allowlist_var("SIMCONNECT_RECV_ID_VOR_LIST_HAS_DME") - .allowlist_var("SIMCONNECT_WAYPOINT_NONE") - .allowlist_var("SIMCONNECT_WAYPOINT_SPEED_REQUESTED") - .allowlist_var("SIMCONNECT_WAYPOINT_THROTTLE_REQUESTED") - .allowlist_var("SIMCONNECT_WAYPOINT_COMPUTE_VERTICAL_SPEED") - .allowlist_var("SIMCONNECT_WAYPOINT_ALTITUDE_IS_AGL") - .allowlist_var("SIMCONNECT_WAYPOINT_ON_GROUND") - .allowlist_var("SIMCONNECT_WAYPOINT_REVERSE") - .allowlist_var("SIMCONNECT_WAYPOINT_WRAP_TO_FIRST") - .allowlist_var("SIMCONNECT_WAYPOINT_ALWAYS_BACKUP") - .allowlist_var("SIMCONNECT_WAYPOINT_KEEP_LAST_HEADING") - .allowlist_var("SIMCONNECT_WAYPOINT_YIELD_TO_USER") - .allowlist_var("SIMCONNECT_WAYPOINT_CAN_REVERSE") - .allowlist_var("SIMCONNECT_EVENT_FLAG_DEFAULT") - .allowlist_var("SIMCONNECT_EVENT_FLAG_FAST_REPEAT_TIMER") - .allowlist_var("SIMCONNECT_EVENT_FLAG_SLOW_REPEAT_TIMER") - .allowlist_var("SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY") - .allowlist_var("SIMCONNECT_DATA_REQUEST_FLAG_DEFAULT") - .allowlist_var("SIMCONNECT_DATA_REQUEST_FLAG_CHANGED") - .allowlist_var("SIMCONNECT_DATA_REQUEST_FLAG_TAGGED") - .allowlist_var("SIMCONNECT_DATA_SET_FLAG_DEFAULT") - .allowlist_var("SIMCONNECT_DATA_SET_FLAG_TAGGED") - .allowlist_var("SIMCONNECT_CREATE_CLIENT_DATA_FLAG_DEFAULT") - .allowlist_var("SIMCONNECT_CREATE_CLIENT_DATA_FLAG_READ_ONLY") - .allowlist_var("SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_DEFAULT") - .allowlist_var("SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_CHANGED") - .allowlist_var("SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_TAGGED") - .allowlist_var("SIMCONNECT_CLIENT_DATA_SET_FLAG_DEFAULT") - .allowlist_var("SIMCONNECT_CLIENT_DATA_SET_FLAG_TAGGED") - .allowlist_var("SIMCONNECT_VIEW_SYSTEM_EVENT_DATA_COCKPIT_2D") - .allowlist_var("SIMCONNECT_VIEW_SYSTEM_EVENT_DATA_COCKPIT_VIRTUAL") - .allowlist_var("SIMCONNECT_VIEW_SYSTEM_EVENT_DATA_ORTHOGONAL") - .allowlist_var("SIMCONNECT_SOUND_SYSTEM_EVENT_DATA_MASTER") - .allowlist_var("UNKNOWN_SENDID") - .allowlist_var("UNKNOWN_INDEX") - .allowlist_var("UNKNOWN_GROUP") - .allowlist_var("SIMCONNECT_CLOUD_STATE_ARRAY_WIDTH") - .allowlist_var("SIMCONNECT_CLOUD_STATE_ARRAY_SIZE") - .allowlist_var("SIMCONNECT_PICK_GROUND") - .allowlist_var("SIMCONNECT_PICK_AI") - .allowlist_var("SIMCONNECT_PICK_SCENERY") - .allowlist_var("SIMCONNECT_PICK_ALL") - .allowlist_var("SIMCONNECT_PICK_COORDSASPIXELS") - - // ==================== TYPES / ENUMS ==================== - .allowlist_type("HANDLE") - .allowlist_type("SIMCONNECT_RECV_ID") - .allowlist_type("SIMCONNECT_DATATYPE") - .allowlist_type("SIMCONNECT_EXCEPTION") - .allowlist_type("SIMCONNECT_SIMOBJECT_TYPE") - .allowlist_type("SIMCONNECT_STATE") - .allowlist_type("SIMCONNECT_PERIOD") - .allowlist_type("SIMCONNECT_MISSION_END") - .allowlist_type("SIMCONNECT_CLIENT_DATA_PERIOD") - .allowlist_type("SIMCONNECT_TEXT_TYPE") - .allowlist_type("SIMCONNECT_TEXT_RESULT") - .allowlist_type("SIMCONNECT_WEATHER_MODE") - .allowlist_type("SIMCONNECT_FACILITY_LIST_TYPE") - .allowlist_type("SIMCONNECT_FACILITY_DATA_TYPE") - .allowlist_type("SIMCONNECT_INPUT_EVENT_TYPE") - .allowlist_type("SIMCONNECT_VOR_FLAGS") - .allowlist_type("SIMCONNECT_WAYPOINT_FLAGS") - .allowlist_type("SIMCONNECT_EVENT_FLAG") - .allowlist_type("SIMCONNECT_DATA_REQUEST_FLAG") - .allowlist_type("SIMCONNECT_DATA_SET_FLAG") - .allowlist_type("SIMCONNECT_CREATE_CLIENT_DATA_FLAG") - .allowlist_type("SIMCONNECT_CLIENT_DATA_REQUEST_FLAG") - .allowlist_type("SIMCONNECT_CLIENT_DATA_SET_FLAG") - .allowlist_type("SIMCONNECT_VIEW_SYSTEM_EVENT_DATA") - .allowlist_type("SIMCONNECT_SOUND_SYSTEM_EVENT_DATA") - .allowlist_type("SIMCONNECT_PICK_FLAGS") - - // ==================== STRUCTS ==================== - .allowlist_type("SIMCONNECT_RECV") - .allowlist_type("SIMCONNECT_RECV_EXCEPTION") - .allowlist_type("SIMCONNECT_RECV_OPEN") - .allowlist_type("SIMCONNECT_RECV_QUIT") - .allowlist_type("SIMCONNECT_RECV_EVENT") - .allowlist_type("SIMCONNECT_RECV_EVENT_FILENAME") - .allowlist_type("SIMCONNECT_RECV_EVENT_OBJECT_ADDREMOVE") - .allowlist_type("SIMCONNECT_RECV_EVENT_FRAME") - .allowlist_type("SIMCONNECT_RECV_EVENT_MULTIPLAYER_SERVER_STARTED") - .allowlist_type("SIMCONNECT_RECV_EVENT_MULTIPLAYER_CLIENT_STARTED") - .allowlist_type("SIMCONNECT_RECV_EVENT_MULTIPLAYER_SESSION_ENDED") - .allowlist_type("SIMCONNECT_RECV_EVENT_RACE_END") - .allowlist_type("SIMCONNECT_RECV_EVENT_RACE_LAP") - .allowlist_type("SIMCONNECT_RECV_SIMOBJECT_DATA") - .allowlist_type("SIMCONNECT_RECV_SIMOBJECT_DATA_BYTYPE") - .allowlist_type("SIMCONNECT_RECV_CLIENT_DATA") - .allowlist_type("SIMCONNECT_RECV_WEATHER_OBSERVATION") - .allowlist_type("SIMCONNECT_RECV_CLOUD_STATE") - .allowlist_type("SIMCONNECT_RECV_ASSIGNED_OBJECT_ID") - .allowlist_type("SIMCONNECT_RECV_RESERVED_KEY") - .allowlist_type("SIMCONNECT_RECV_SYSTEM_STATE") - .allowlist_type("SIMCONNECT_RECV_CUSTOM_ACTION") - .allowlist_type("SIMCONNECT_RECV_EVENT_WEATHER_MODE") - .allowlist_type("SIMCONNECT_RECV_FACILITIES_LIST") - .allowlist_type("SIMCONNECT_DATA_FACILITY_AIRPORT") - .allowlist_type("SIMCONNECT_RECV_AIRPORT_LIST") - .allowlist_type("SIMCONNECT_DATA_FACILITY_WAYPOINT") - .allowlist_type("SIMCONNECT_RECV_WAYPOINT_LIST") - .allowlist_type("SIMCONNECT_DATA_FACILITY_NDB") - .allowlist_type("SIMCONNECT_RECV_NDB_LIST") - .allowlist_type("SIMCONNECT_DATA_FACILITY_VOR") - .allowlist_type("SIMCONNECT_RECV_VOR_LIST") - .allowlist_type("SIMCONNECT_RECV_PICK") - .allowlist_type("SIMCONNECT_RECV_EVENT_EX1") - .allowlist_type("SIMCONNECT_DATA_RACE_RESULT") - .allowlist_type("SIMCONNECT_RECV_FACILITY_DATA") - .allowlist_type("SIMCONNECT_RECV_FACILITY_DATA_END") - .allowlist_type("SIMCONNECT_ICAO") - .allowlist_type("SIMCONNECT_FACILITY_MINIMAL") - .allowlist_type("SIMCONNECT_RECV_FACILITY_MINIMAL_LIST") - .allowlist_type("SIMCONNECT_DATA_PBH") - .allowlist_type("SIMCONNECT_JETWAY_DATA") - .allowlist_type("SIMCONNECT_RECV_JETWAY_DATA") - .allowlist_type("SIMCONNECT_RECV_ACTION_CALLBACK") - .allowlist_type("SIMCONNECT_INPUT_EVENT_DESCRIPTOR") - .allowlist_type("SIMCONNECT_RECV_ENUMERATE_INPUT_EVENTS") - .allowlist_type("SIMCONNECT_RECV_GET_INPUT_EVENT") - .allowlist_type("SIMCONNECT_RECV_SUBSCRIBE_INPUT_EVENT") - .allowlist_type("SIMCONNECT_RECV_ENUMERATE_INPUT_EVENT_PARAMS") - .allowlist_type("SIMCONNECT_VERSION_BASE_TYPE") - .allowlist_type("SIMCONNECT_CONTROLLER_ITEM") - .allowlist_type("SIMCONNECT_RECV_CONTROLLERS_LIST") - .allowlist_type("SIMCONNECT_RECV_LIST_TEMPLATE") - .allowlist_type("SIMCONNECT_DATA_INITPOSITION") - .allowlist_type("SIMCONNECT_DATA_MARKERSTATE") - .allowlist_type("SIMCONNECT_DATA_WAYPOINT") - .allowlist_type("SIMCONNECT_DATA_LATLONALT") - .allowlist_type("SIMCONNECT_DATA_XYZ") - - // ==================== FUNCTIONS ==================== - .allowlist_function("SimConnect_MapClientEventToSimEvent") - .allowlist_function("SimConnect_TransmitClientEvent") - .allowlist_function("SimConnect_SetSystemEventState") - .allowlist_function("SimConnect_AddClientEventToNotificationGroup") - .allowlist_function("SimConnect_RemoveClientEvent") - .allowlist_function("SimConnect_SetNotificationGroupPriority") - .allowlist_function("SimConnect_ClearNotificationGroup") - .allowlist_function("SimConnect_RequestNotificationGroup") - .allowlist_function("SimConnect_AddToDataDefinition") - .allowlist_function("SimConnect_ClearDataDefinition") - .allowlist_function("SimConnect_RequestDataOnSimObject") - .allowlist_function("SimConnect_RequestDataOnSimObjectType") - .allowlist_function("SimConnect_SetDataOnSimObject") - .allowlist_function("SimConnect_MapInputEventToClientEvent") - .allowlist_function("SimConnect_SetInputGroupPriority") - .allowlist_function("SimConnect_RemoveInputEvent") - .allowlist_function("SimConnect_ClearInputGroup") - .allowlist_function("SimConnect_SetInputGroupState") - .allowlist_function("SimConnect_RequestReservedKey") - .allowlist_function("SimConnect_SubscribeToSystemEvent") - .allowlist_function("SimConnect_UnsubscribeFromSystemEvent") - .allowlist_function("SimConnect_WeatherRequestInterpolatedObservation") - .allowlist_function("SimConnect_WeatherRequestObservationAtStation") - .allowlist_function("SimConnect_WeatherRequestObservationAtNearestStation") - .allowlist_function("SimConnect_WeatherCreateStation") - .allowlist_function("SimConnect_WeatherRemoveStation") - .allowlist_function("SimConnect_WeatherSetObservation") - .allowlist_function("SimConnect_WeatherSetModeServer") - .allowlist_function("SimConnect_WeatherSetModeTheme") - .allowlist_function("SimConnect_WeatherSetModeGlobal") - .allowlist_function("SimConnect_WeatherSetModeCustom") - .allowlist_function("SimConnect_WeatherSetDynamicUpdateRate") - .allowlist_function("SimConnect_WeatherRequestCloudState") - .allowlist_function("SimConnect_WeatherCreateThermal") - .allowlist_function("SimConnect_WeatherRemoveThermal") - .allowlist_function("SimConnect_AICreateParkedATCAircraft") - .allowlist_function("SimConnect_AICreateEnrouteATCAircraft") - .allowlist_function("SimConnect_AICreateNonATCAircraft") - .allowlist_function("SimConnect_AICreateSimulatedObject") - .allowlist_function("SimConnect_AIReleaseControl") - .allowlist_function("SimConnect_AIRemoveObject") - .allowlist_function("SimConnect_AISetAircraftFlightPlan") - .allowlist_function("SimConnect_ExecuteMissionAction") - .allowlist_function("SimConnect_CompleteCustomMissionAction") - .allowlist_function("SimConnect_Close") - .allowlist_function("SimConnect_RetrieveString") - .allowlist_function("SimConnect_GetLastSentPacketID") - .allowlist_function("SimConnect_Open") - .allowlist_function("SimConnect_CallDispatch") - .allowlist_function("SimConnect_GetNextDispatch") - .allowlist_function("SimConnect_RequestResponseTimes") - .allowlist_function("SimConnect_InsertString") - .allowlist_function("SimConnect_CameraSetRelative6DOF") - .allowlist_function("SimConnect_MenuAddItem") - .allowlist_function("SimConnect_MenuDeleteItem") - .allowlist_function("SimConnect_MenuAddSubItem") - .allowlist_function("SimConnect_MenuDeleteSubItem") - .allowlist_function("SimConnect_RequestSystemState") - .allowlist_function("SimConnect_SetSystemState") - .allowlist_function("SimConnect_MapClientDataNameToID") - .allowlist_function("SimConnect_CreateClientData") - .allowlist_function("SimConnect_AddToClientDataDefinition") - .allowlist_function("SimConnect_ClearClientDataDefinition") - .allowlist_function("SimConnect_RequestClientData") - .allowlist_function("SimConnect_SetClientData") - .allowlist_function("SimConnect_FlightLoad") - .allowlist_function("SimConnect_FlightSave") - .allowlist_function("SimConnect_FlightPlanLoad") - .allowlist_function("SimConnect_Text") - .allowlist_function("SimConnect_SubscribeToFacilities") - .allowlist_function("SimConnect_UnsubscribeToFacilities") - .allowlist_function("SimConnect_RequestFacilitiesList") - .allowlist_function("SimConnect_TransmitClientEvent_EX1") - .allowlist_function("SimConnect_AddToFacilityDefinition") - .allowlist_function("SimConnect_RequestFacilityData") - .allowlist_function("SimConnect_SubscribeToFacilities_EX1") - .allowlist_function("SimConnect_UnsubscribeToFacilities_EX1") - .allowlist_function("SimConnect_RequestFacilitiesList_EX1") - .allowlist_function("SimConnect_RequestFacilityData_EX1") - .allowlist_function("SimConnect_RequestJetwayData") - .allowlist_function("SimConnect_EnumerateControllers") - .allowlist_function("SimConnect_MapInputEventToClientEvent_EX1") - .allowlist_function("SimConnect_ExecuteAction") - .allowlist_function("SimConnect_EnumerateInputEvents") - .allowlist_function("SimConnect_GetInputEvent") - .allowlist_function("SimConnect_SetInputEvent") - .allowlist_function("SimConnect_SubscribeInputEvent") - .allowlist_function("SimConnect_UnsubscribeInputEvent") - .allowlist_function("SimConnect_EnumerateInputEventParams") - .allowlist_function("SimConnect_AddFacilityDataDefinitionFilter") - .allowlist_function("SimConnect_ClearAllFacilityDataDefinitionFilters") - - .impl_debug(true) - .generate() - .expect("Unable to generate bindings"); - - let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); - bindings - .write_to_file(out_path.join("bindings.rs")) - .expect("Couldn't write bindings!"); -} diff --git a/examples/aircraft_updates/main.rs b/examples/aircraft_updates/main.rs index 5e6eedf..44ae0ce 100644 --- a/examples/aircraft_updates/main.rs +++ b/examples/aircraft_updates/main.rs @@ -1,6 +1,5 @@ use std::thread::sleep; use std::time::Duration; - use simconnect::DispatchResult; struct DataStruct { @@ -8,9 +7,10 @@ struct DataStruct { lon: f64, alt: f64, } + fn main() { let mut conn = simconnect::SimConnector::new(); - conn.connect("Simple Program"); // Intialize connection with SimConnect + conn.connect("Simple Program"); // Initialize connection with SimConnect conn.add_data_definition( 0, "PLANE LATITUDE", @@ -34,7 +34,7 @@ fn main() { simconnect::SIMCONNECT_DATATYPE_SIMCONNECT_DATATYPE_FLOAT64, u32::MAX, 1.0, - ); //define_id, units, data_type, datum_id, epsilon (update threshold) + ); // define_id, units, data_type, datum_id, epsilon (update threshold) conn.request_data_on_sim_object( 0, 0, @@ -44,7 +44,7 @@ fn main() { 0, 0, 0, - ); //request_id, define_id, object_id (user), period, falgs, origin, interval, limit - tells simconnect to send data for the defined id and on the user aircraft + ); // request_id, define_id, object_id (user), period, flags, origin, interval, limit - tells simconnect to send data for the defined id and on the user aircraft loop { match conn.get_next_message() { diff --git a/examples/aircraft_updates_on_change/main.rs b/examples/aircraft_updates_on_change/main.rs index f4211a0..4e51592 100644 --- a/examples/aircraft_updates_on_change/main.rs +++ b/examples/aircraft_updates_on_change/main.rs @@ -1,9 +1,9 @@ -use simconnect::{DispatchResult, DWORD}; use std::ptr::read_unaligned; use std::thread::sleep; use std::time::Duration; +use simconnect::{DispatchResult, DWORD}; -// To allign the memory we have to set a fixed max size to the returned variables from the game +// To align the memory we have to set a fixed max size to the returned variables from the game const MAX_RETURNED_ITEMS: usize = 255; // Rust will add padding to the inner parts of a struct if it isn't marked as packed @@ -54,7 +54,7 @@ fn main() { simconnect::SIMCONNECT_DATATYPE_SIMCONNECT_DATATYPE_FLOAT64, 3, 100.0, - ); //define_id, units, data_type, datum_id, epsilon (update threshold) + ); // define_id, units, data_type, datum_id, epsilon (update threshold) // Here we define all our variabes that get returned as Strings // Notice how the define_id differs from the float values @@ -82,7 +82,7 @@ fn main() { 0, 0, 0, - ); //request_id, define_id, object_id (user), period, falgs, origin, interval, limit - tells simconnect to send data for the defined id and on the user aircraft + ); // request_id, define_id, object_id (user), period, flags, origin, interval, limit - tells simconnect to send data for the defined id and on the user aircraft // Request the data from our define_id 1 (strings) // The request_id has to differ from the float request. Or else it will overwrite the previous request conn.request_data_on_sim_object( @@ -95,7 +95,7 @@ fn main() { 0, 0, 0, - ); //request_id, define_id, object_id (user), period, falgs, origin, interval, limit - tells simconnect to send data for the defined id and on the user aircraft + ); // request_id, define_id, object_id (user), period, flags, origin, interval, limit - tells simconnect to send data for the defined id and on the user aircraft loop { match conn.get_next_message() { diff --git a/simulators/FS2020/Cargo.toml b/simulators/FS2020/Cargo.toml new file mode 100644 index 0000000..08669d2 --- /dev/null +++ b/simulators/FS2020/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "simconnect-fs2020" +license = "MIT" +description = "Rust bindings for SimConnect" +version = "0.5.0" +authors = ["Connor T"] +edition = "2021" + +[build-dependencies] +bindgen = "0.72" diff --git a/SimConnect.dll b/simulators/FS2020/SimConnect.dll similarity index 83% rename from SimConnect.dll rename to simulators/FS2020/SimConnect.dll index 2aa284c..8f0fe28 100644 Binary files a/SimConnect.dll and b/simulators/FS2020/SimConnect.dll differ diff --git a/simulators/FS2020/build.rs b/simulators/FS2020/build.rs new file mode 100644 index 0000000..a043df0 --- /dev/null +++ b/simulators/FS2020/build.rs @@ -0,0 +1,305 @@ +use std::{env, path::PathBuf}; + +fn main() { + let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); + let lib_dir = PathBuf::from(manifest_dir).join("libsrc").join("lib"); + + println!("cargo:rustc-link-search={}", lib_dir.display()); + println!("cargo:rustc-link-lib=static=SimConnect"); + + let handle = std::thread::Builder::new() + .stack_size(128 * 1024 * 1024) + .spawn(|| { + let mut builder = bindgen::Builder::default() + .header("libsrc/include/SimConnect.hpp") + .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) + .impl_debug(true); + + // ==================== CONSTANTS / VARS ==================== + let vars = [ + "SIMCONNECT_UNUSED", + "SIMCONNECT_OBJECT_ID_USER", + "SIMCONNECT_CAMERA_IGNORE_FIELD", + "SIMCONNECT_CLIENTDATA_MAX_SIZE", + "SIMCONNECT_GROUP_PRIORITY_HIGHEST", + "SIMCONNECT_GROUP_PRIORITY_HIGHEST_MASKABLE", + "SIMCONNECT_GROUP_PRIORITY_STANDARD", + "SIMCONNECT_GROUP_PRIORITY_DEFAULT", + "SIMCONNECT_GROUP_PRIORITY_LOWEST", + "MAX_METAR_LENGTH", + "MAX_THERMAL_SIZE", + "MAX_THERMAL_RATE", + "INITPOSITION_AIRSPEED_CRUISE", + "INITPOSITION_AIRSPEED_KEEP", + "SIMCONNECT_CLIENTDATATYPE_INT8", + "SIMCONNECT_CLIENTDATATYPE_INT16", + "SIMCONNECT_CLIENTDATATYPE_INT32", + "SIMCONNECT_CLIENTDATATYPE_INT64", + "SIMCONNECT_CLIENTDATATYPE_FLOAT32", + "SIMCONNECT_CLIENTDATATYPE_FLOAT64", + "SIMCONNECT_CLIENTDATAOFFSET_AUTO", + "SIMCONNECT_OPEN_CONFIGINDEX_LOCAL", + "SIMCONNECT_RECV_ID_VOR_LIST_HAS_NAV_SIGNAL", + "SIMCONNECT_RECV_ID_VOR_LIST_HAS_LOCALIZER", + "SIMCONNECT_RECV_ID_VOR_LIST_HAS_GLIDE_SLOPE", + "SIMCONNECT_RECV_ID_VOR_LIST_HAS_DME", + "SIMCONNECT_WAYPOINT_NONE", + "SIMCONNECT_WAYPOINT_SPEED_REQUESTED", + "SIMCONNECT_WAYPOINT_THROTTLE_REQUESTED", + "SIMCONNECT_WAYPOINT_COMPUTE_VERTICAL_SPEED", + "SIMCONNECT_WAYPOINT_ALTITUDE_IS_AGL", + "SIMCONNECT_WAYPOINT_ON_GROUND", + "SIMCONNECT_WAYPOINT_REVERSE", + "SIMCONNECT_WAYPOINT_WRAP_TO_FIRST", + "SIMCONNECT_WAYPOINT_ALWAYS_BACKUP", + "SIMCONNECT_WAYPOINT_KEEP_LAST_HEADING", + "SIMCONNECT_WAYPOINT_YIELD_TO_USER", + "SIMCONNECT_WAYPOINT_CAN_REVERSE", + "SIMCONNECT_EVENT_FLAG_DEFAULT", + "SIMCONNECT_EVENT_FLAG_FAST_REPEAT_TIMER", + "SIMCONNECT_EVENT_FLAG_SLOW_REPEAT_TIMER", + "SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY", + "SIMCONNECT_DATA_REQUEST_FLAG_DEFAULT", + "SIMCONNECT_DATA_REQUEST_FLAG_CHANGED", + "SIMCONNECT_DATA_REQUEST_FLAG_TAGGED", + "SIMCONNECT_DATA_SET_FLAG_DEFAULT", + "SIMCONNECT_DATA_SET_FLAG_TAGGED", + "SIMCONNECT_CREATE_CLIENT_DATA_FLAG_DEFAULT", + "SIMCONNECT_CREATE_CLIENT_DATA_FLAG_READ_ONLY", + "SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_DEFAULT", + "SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_CHANGED", + "SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_TAGGED", + "SIMCONNECT_CLIENT_DATA_SET_FLAG_DEFAULT", + "SIMCONNECT_CLIENT_DATA_SET_FLAG_TAGGED", + "SIMCONNECT_VIEW_SYSTEM_EVENT_DATA_COCKPIT_2D", + "SIMCONNECT_VIEW_SYSTEM_EVENT_DATA_COCKPIT_VIRTUAL", + "SIMCONNECT_VIEW_SYSTEM_EVENT_DATA_ORTHOGONAL", + "SIMCONNECT_SOUND_SYSTEM_EVENT_DATA_MASTER", + "UNKNOWN_SENDID", + "UNKNOWN_INDEX", + "UNKNOWN_GROUP", + "SIMCONNECT_CLOUD_STATE_ARRAY_WIDTH", + "SIMCONNECT_CLOUD_STATE_ARRAY_SIZE", + "SIMCONNECT_PICK_GROUND", + "SIMCONNECT_PICK_AI", + "SIMCONNECT_PICK_SCENERY", + "SIMCONNECT_PICK_ALL", + "SIMCONNECT_PICK_COORDSASPIXELS", + ]; + + for v in vars { + builder = builder.allowlist_var(v); + } + + // ==================== TYPES / ENUMS ==================== + let types = [ + "HANDLE", + "SIMCONNECT_RECV_ID", + "SIMCONNECT_DATATYPE", + "SIMCONNECT_EXCEPTION", + "SIMCONNECT_SIMOBJECT_TYPE", + "SIMCONNECT_STATE", + "SIMCONNECT_PERIOD", + "SIMCONNECT_MISSION_END", + "SIMCONNECT_CLIENT_DATA_PERIOD", + "SIMCONNECT_TEXT_TYPE", + "SIMCONNECT_TEXT_RESULT", + "SIMCONNECT_WEATHER_MODE", + "SIMCONNECT_FACILITY_LIST_TYPE", + "SIMCONNECT_FACILITY_DATA_TYPE", + "SIMCONNECT_INPUT_EVENT_TYPE", + "SIMCONNECT_VOR_FLAGS", + "SIMCONNECT_WAYPOINT_FLAGS", + "SIMCONNECT_EVENT_FLAG", + "SIMCONNECT_DATA_REQUEST_FLAG", + "SIMCONNECT_DATA_SET_FLAG", + "SIMCONNECT_CREATE_CLIENT_DATA_FLAG", + "SIMCONNECT_CLIENT_DATA_REQUEST_FLAG", + "SIMCONNECT_CLIENT_DATA_SET_FLAG", + "SIMCONNECT_VIEW_SYSTEM_EVENT_DATA", + "SIMCONNECT_SOUND_SYSTEM_EVENT_DATA", + "SIMCONNECT_PICK_FLAGS", + ]; + + for t in types { + builder = builder.allowlist_type(t); + } + + // ==================== STRUCTS ==================== + let structs = [ + "SIMCONNECT_RECV", + "SIMCONNECT_RECV_EXCEPTION", + "SIMCONNECT_RECV_OPEN", + "SIMCONNECT_RECV_QUIT", + "SIMCONNECT_RECV_EVENT", + "SIMCONNECT_RECV_EVENT_FILENAME", + "SIMCONNECT_RECV_EVENT_OBJECT_ADDREMOVE", + "SIMCONNECT_RECV_EVENT_FRAME", + "SIMCONNECT_RECV_EVENT_MULTIPLAYER_SERVER_STARTED", + "SIMCONNECT_RECV_EVENT_MULTIPLAYER_CLIENT_STARTED", + "SIMCONNECT_RECV_EVENT_MULTIPLAYER_SESSION_ENDED", + "SIMCONNECT_RECV_EVENT_RACE_END", + "SIMCONNECT_RECV_EVENT_RACE_LAP", + "SIMCONNECT_RECV_SIMOBJECT_DATA", + "SIMCONNECT_RECV_SIMOBJECT_DATA_BYTYPE", + "SIMCONNECT_RECV_CLIENT_DATA", + "SIMCONNECT_RECV_WEATHER_OBSERVATION", + "SIMCONNECT_RECV_CLOUD_STATE", + "SIMCONNECT_RECV_ASSIGNED_OBJECT_ID", + "SIMCONNECT_RECV_RESERVED_KEY", + "SIMCONNECT_RECV_SYSTEM_STATE", + "SIMCONNECT_RECV_CUSTOM_ACTION", + "SIMCONNECT_RECV_EVENT_WEATHER_MODE", + "SIMCONNECT_RECV_FACILITIES_LIST", + "SIMCONNECT_DATA_FACILITY_AIRPORT", + "SIMCONNECT_RECV_AIRPORT_LIST", + "SIMCONNECT_DATA_FACILITY_WAYPOINT", + "SIMCONNECT_RECV_WAYPOINT_LIST", + "SIMCONNECT_DATA_FACILITY_NDB", + "SIMCONNECT_RECV_NDB_LIST", + "SIMCONNECT_DATA_FACILITY_VOR", + "SIMCONNECT_RECV_VOR_LIST", + "SIMCONNECT_RECV_EVENT_EX1", + "SIMCONNECT_DATA_RACE_RESULT", + "SIMCONNECT_RECV_FACILITY_DATA", + "SIMCONNECT_RECV_FACILITY_DATA_END", + "SIMCONNECT_ICAO", + "SIMCONNECT_FACILITY_MINIMAL", + "SIMCONNECT_RECV_FACILITY_MINIMAL_LIST", + "SIMCONNECT_DATA_PBH", + "SIMCONNECT_JETWAY_DATA", + "SIMCONNECT_RECV_JETWAY_DATA", + "SIMCONNECT_RECV_ACTION_CALLBACK", + "SIMCONNECT_INPUT_EVENT_DESCRIPTOR", + "SIMCONNECT_RECV_ENUMERATE_INPUT_EVENTS", + "SIMCONNECT_RECV_GET_INPUT_EVENT", + "SIMCONNECT_RECV_SUBSCRIBE_INPUT_EVENT", + "SIMCONNECT_RECV_ENUMERATE_INPUT_EVENT_PARAMS", + "SIMCONNECT_VERSION_BASE_TYPE", + "SIMCONNECT_CONTROLLER_ITEM", + "SIMCONNECT_RECV_CONTROLLERS_LIST", + "SIMCONNECT_RECV_LIST_TEMPLATE", + "SIMCONNECT_DATA_INITPOSITION", + "SIMCONNECT_DATA_MARKERSTATE", + "SIMCONNECT_DATA_WAYPOINT", + "SIMCONNECT_DATA_LATLONALT", + "SIMCONNECT_DATA_XYZ", + "SIMCONNECT_RECV_PICK", + ]; + + for s in structs { + builder = builder.allowlist_type(s); + } + + // ==================== FUNCTIONS ==================== + let functions = [ + "SimConnect_MapClientEventToSimEvent", + "SimConnect_TransmitClientEvent", + "SimConnect_SetSystemEventState", + "SimConnect_AddClientEventToNotificationGroup", + "SimConnect_RemoveClientEvent", + "SimConnect_SetNotificationGroupPriority", + "SimConnect_ClearNotificationGroup", + "SimConnect_RequestNotificationGroup", + "SimConnect_AddToDataDefinition", + "SimConnect_ClearDataDefinition", + "SimConnect_RequestDataOnSimObject", + "SimConnect_RequestDataOnSimObjectType", + "SimConnect_SetDataOnSimObject", + "SimConnect_MapInputEventToClientEvent", + "SimConnect_SetInputGroupPriority", + "SimConnect_RemoveInputEvent", + "SimConnect_ClearInputGroup", + "SimConnect_SetInputGroupState", + "SimConnect_RequestReservedKey", + "SimConnect_SubscribeToSystemEvent", + "SimConnect_UnsubscribeFromSystemEvent", + "SimConnect_WeatherRequestInterpolatedObservation", + "SimConnect_WeatherRequestObservationAtStation", + "SimConnect_WeatherRequestObservationAtNearestStation", + "SimConnect_WeatherCreateStation", + "SimConnect_WeatherRemoveStation", + "SimConnect_WeatherSetObservation", + "SimConnect_WeatherSetModeServer", + "SimConnect_WeatherSetModeTheme", + "SimConnect_WeatherSetModeGlobal", + "SimConnect_WeatherSetModeCustom", + "SimConnect_WeatherSetDynamicUpdateRate", + "SimConnect_WeatherRequestCloudState", + "SimConnect_WeatherCreateThermal", + "SimConnect_WeatherRemoveThermal", + "SimConnect_AICreateParkedATCAircraft", + "SimConnect_AICreateEnrouteATCAircraft", + "SimConnect_AICreateNonATCAircraft", + "SimConnect_AICreateSimulatedObject", + "SimConnect_AIReleaseControl", + "SimConnect_AIRemoveObject", + "SimConnect_AISetAircraftFlightPlan", + "SimConnect_ExecuteMissionAction", + "SimConnect_CompleteCustomMissionAction", + "SimConnect_Close", + "SimConnect_RetrieveString", + "SimConnect_GetLastSentPacketID", + "SimConnect_Open", + "SimConnect_CallDispatch", + "SimConnect_GetNextDispatch", + "SimConnect_RequestResponseTimes", + "SimConnect_InsertString", + "SimConnect_CameraSetRelative6DOF", + "SimConnect_MenuAddItem", + "SimConnect_MenuDeleteItem", + "SimConnect_MenuAddSubItem", + "SimConnect_MenuDeleteSubItem", + "SimConnect_RequestSystemState", + "SimConnect_SetSystemState", + "SimConnect_MapClientDataNameToID", + "SimConnect_CreateClientData", + "SimConnect_AddToClientDataDefinition", + "SimConnect_ClearClientDataDefinition", + "SimConnect_RequestClientData", + "SimConnect_SetClientData", + "SimConnect_FlightLoad", + "SimConnect_FlightSave", + "SimConnect_FlightPlanLoad", + "SimConnect_Text", + "SimConnect_SubscribeToFacilities", + "SimConnect_UnsubscribeToFacilities", + "SimConnect_RequestFacilitiesList", + "SimConnect_TransmitClientEvent_EX1", + "SimConnect_AddToFacilityDefinition", + "SimConnect_RequestFacilityData", + "SimConnect_SubscribeToFacilities_EX1", + "SimConnect_UnsubscribeToFacilities_EX1", + "SimConnect_RequestFacilitiesList_EX1", + "SimConnect_RequestFacilityData_EX1", + "SimConnect_RequestJetwayData", + "SimConnect_EnumerateControllers", + "SimConnect_MapInputEventToClientEvent_EX1", + "SimConnect_ExecuteAction", + "SimConnect_EnumerateInputEvents", + "SimConnect_GetInputEvent", + "SimConnect_SetInputEvent", + "SimConnect_SubscribeInputEvent", + "SimConnect_UnsubscribeInputEvent", + "SimConnect_EnumerateInputEventParams", + "SimConnect_AddFacilityDataDefinitionFilter", + "SimConnect_ClearAllFacilityDataDefinitionFilters", + ]; + + for f in functions { + builder = builder.allowlist_function(f); + } + + let bindings = builder + .generate() + .expect("Unable to generate bindings"); + + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); + bindings + .write_to_file(out_path.join("bindings.rs")) + .expect("Couldn't write bindings!"); + }) + .expect("Failed to spawn bindgen thread"); + + handle.join().expect("Bindgen thread panicked"); +} diff --git a/libsrc/include/SimConnect.hpp b/simulators/FS2020/libsrc/include/SimConnect.hpp similarity index 100% rename from libsrc/include/SimConnect.hpp rename to simulators/FS2020/libsrc/include/SimConnect.hpp diff --git a/libsrc/lib/SimConnect.lib b/simulators/FS2020/libsrc/lib/SimConnect.lib similarity index 100% rename from libsrc/lib/SimConnect.lib rename to simulators/FS2020/libsrc/lib/SimConnect.lib diff --git a/simulators/FS2020/src/lib.rs b/simulators/FS2020/src/lib.rs new file mode 100644 index 0000000..a3169ad --- /dev/null +++ b/simulators/FS2020/src/lib.rs @@ -0,0 +1,1193 @@ +#![allow(clippy::too_many_arguments, clippy::missing_safety_doc)] +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] + +use std::ffi::CString; +use std::ptr; + +include!(concat!(env!("OUT_DIR"), "/bindings.rs")); + +#[derive(Debug)] +pub enum DispatchResult<'a> { + Null, + Exception(&'a SIMCONNECT_RECV_EXCEPTION), + Open(&'a SIMCONNECT_RECV_OPEN), + Quit(&'a SIMCONNECT_RECV_QUIT), + Event(&'a SIMCONNECT_RECV_EVENT), + EventObjectAddRemove(&'a SIMCONNECT_RECV_EVENT_OBJECT_ADDREMOVE), + EventFilename(&'a SIMCONNECT_RECV_EVENT_FILENAME), + EventFrame(&'a SIMCONNECT_RECV_EVENT_FRAME), + SimObjectData(&'a SIMCONNECT_RECV_SIMOBJECT_DATA), + SimObjectDataByType(&'a SIMCONNECT_RECV_SIMOBJECT_DATA_BYTYPE), + WeatherObservation(&'a SIMCONNECT_RECV_WEATHER_OBSERVATION), + CloudState(&'a SIMCONNECT_RECV_CLOUD_STATE), + AssignedObjectId(&'a SIMCONNECT_RECV_ASSIGNED_OBJECT_ID), + ReservedKey(&'a SIMCONNECT_RECV_RESERVED_KEY), + CustomAction(&'a SIMCONNECT_RECV_CUSTOM_ACTION), + SystemState(&'a SIMCONNECT_RECV_SYSTEM_STATE), + ClientData(&'a SIMCONNECT_RECV_CLIENT_DATA), + EventWeatherMode(&'a SIMCONNECT_RECV_EVENT_WEATHER_MODE), + AirportList(&'a SIMCONNECT_RECV_AIRPORT_LIST), + VorList(&'a SIMCONNECT_RECV_VOR_LIST), + NdbList(&'a SIMCONNECT_RECV_NDB_LIST), + WaypointList(&'a SIMCONNECT_RECV_WAYPOINT_LIST), + EventMultiplayerServerStarted(&'a SIMCONNECT_RECV_EVENT_MULTIPLAYER_SERVER_STARTED), + EventMultiplayerClientStarted(&'a SIMCONNECT_RECV_EVENT_MULTIPLAYER_CLIENT_STARTED), + EventMultiplayerSessionEnded(&'a SIMCONNECT_RECV_EVENT_MULTIPLAYER_SESSION_ENDED), + EventRaceEnd(&'a SIMCONNECT_RECV_EVENT_RACE_END), + EventRaceLap(&'a SIMCONNECT_RECV_EVENT_RACE_LAP), + EventEx1(&'a SIMCONNECT_RECV_EVENT_EX1), + FacilityData(&'a SIMCONNECT_RECV_FACILITY_DATA), + FacilityDataEnd(&'a SIMCONNECT_RECV_FACILITY_DATA_END), + FacilityMinimalList(&'a SIMCONNECT_RECV_FACILITY_MINIMAL_LIST), + JetwayData(&'a SIMCONNECT_RECV_JETWAY_DATA), + ActionCallback(&'a SIMCONNECT_RECV_ACTION_CALLBACK), + EnumerateInputEvents(&'a SIMCONNECT_RECV_ENUMERATE_INPUT_EVENTS), + GetInputEvent(&'a SIMCONNECT_RECV_GET_INPUT_EVENT), + SubscribeInputEvent(&'a SIMCONNECT_RECV_SUBSCRIBE_INPUT_EVENT), + EnumerateInputEventParams(&'a SIMCONNECT_RECV_ENUMERATE_INPUT_EVENT_PARAMS), + ControllersList(&'a SIMCONNECT_RECV_CONTROLLERS_LIST), +} + +#[derive(Debug)] +pub struct SimConnector { + handle: HANDLE, +} + +impl Default for SimConnector { + fn default() -> Self { + Self { handle: ptr::null_mut() } + } +} + +impl SimConnector { + pub fn new() -> Self { + Self::default() + } + + // ==================== Connection & Lifecycle ==================== + + pub fn connect(&mut self, program_name: &str) -> bool { + let name = cstring(program_name); + + unsafe { + SimConnect_Open( + &mut self.handle, + name.as_ptr(), + ptr::null_mut(), + 0, + ptr::null_mut(), + 0, + ) == 0 + } + } + + pub fn close(&mut self) -> bool { + if self.handle.is_null() { + return true; + } + let result = unsafe { SimConnect_Close(self.handle) == 0 }; + self.handle = ptr::null_mut(); + result + } + + // ==================== Data Definition ==================== + + pub fn add_data_definition( + &self, + define_id: SIMCONNECT_DATA_DEFINITION_ID, + datum_name: &str, + units_name: &str, + datum_type: SIMCONNECT_DATATYPE, + epsilon: f32, + datum_id: DWORD, + ) -> bool { + let name = cstring(datum_name); + let units = cstring(units_name); + + unsafe { + SimConnect_AddToDataDefinition( + self.handle, + define_id, + name.as_ptr(), + units.as_ptr(), + datum_type, + epsilon, + datum_id, + ) == 0 + } + } + + pub fn clear_data_definition(&self, define_id: SIMCONNECT_DATA_DEFINITION_ID) -> bool { + unsafe { SimConnect_ClearDataDefinition(self.handle, define_id) == 0 } + } + + // ==================== Events ==================== + + pub fn map_client_event_to_sim_event( + &self, + event_id: SIMCONNECT_CLIENT_EVENT_ID, + event_name: &str, + ) -> bool { + let name = cstring(event_name); + unsafe { SimConnect_MapClientEventToSimEvent(self.handle, event_id, name.as_ptr()) == 0 } + } + + pub fn subscribe_to_system_event( + &self, + event_id: SIMCONNECT_CLIENT_EVENT_ID, + event_name: &str, + ) -> bool { + let name = cstring(event_name); + unsafe { + SimConnect_SubscribeToSystemEvent(self.handle, event_id, name.as_ptr()) == 0 + } + } + + pub fn unsubscribe_from_system_event(&self, event_id: SIMCONNECT_CLIENT_EVENT_ID) -> bool { + unsafe { SimConnect_UnsubscribeFromSystemEvent(self.handle, event_id) == 0 } + } + + pub fn set_system_event_state( + &self, + event_id: SIMCONNECT_CLIENT_EVENT_ID, + state: SIMCONNECT_STATE, + ) -> bool { + unsafe { SimConnect_SetSystemEventState(self.handle, event_id, state) == 0 } + } + + pub fn transmit_client_event( + &self, + object_id: SIMCONNECT_OBJECT_ID, + event_id: SIMCONNECT_CLIENT_EVENT_ID, + dw_data: DWORD, + group_id: SIMCONNECT_NOTIFICATION_GROUP_ID, + flags: SIMCONNECT_EVENT_FLAG, + ) -> bool { + unsafe { + SimConnect_TransmitClientEvent( + self.handle, + object_id, + event_id, + dw_data, + group_id, + flags, + ) == 0 + } + } + + pub fn add_client_event_to_notification_group( + &self, + group_id: SIMCONNECT_NOTIFICATION_GROUP_ID, + event_id: SIMCONNECT_CLIENT_EVENT_ID, + maskable: bool, + ) -> bool { + unsafe { + SimConnect_AddClientEventToNotificationGroup( + self.handle, + group_id, + event_id, + maskable as i32, + ) == 0 + } + } + + pub fn set_notification_group_priority( + &self, + group_id: SIMCONNECT_NOTIFICATION_GROUP_ID, + priority: DWORD, + ) -> bool { + unsafe { + SimConnect_SetNotificationGroupPriority(self.handle, group_id, priority) == 0 + } + } + + pub fn remove_client_event( + &self, + group_id: SIMCONNECT_NOTIFICATION_GROUP_ID, + event_id: SIMCONNECT_CLIENT_EVENT_ID, + ) -> bool { + unsafe { SimConnect_RemoveClientEvent(self.handle, group_id, event_id) == 0 } + } + + pub fn clear_notification_group(&self, group_id: SIMCONNECT_NOTIFICATION_GROUP_ID) -> bool { + unsafe { SimConnect_ClearNotificationGroup(self.handle, group_id) == 0 } + } + + pub fn request_notification_group( + &self, + group_id: SIMCONNECT_NOTIFICATION_GROUP_ID, + reserved: DWORD, + flags: DWORD, + ) -> bool { + unsafe { + SimConnect_RequestNotificationGroup(self.handle, group_id, reserved, flags) == 0 + } + } + + pub fn transmit_client_event_ex1( + &self, + object_id: SIMCONNECT_OBJECT_ID, + event_id: SIMCONNECT_CLIENT_EVENT_ID, + group_id: SIMCONNECT_NOTIFICATION_GROUP_ID, + flags: SIMCONNECT_EVENT_FLAG, + data0: DWORD, + data1: DWORD, + data2: DWORD, + data3: DWORD, + data4: DWORD, + ) -> bool { + unsafe { + SimConnect_TransmitClientEvent_EX1( + self.handle, + object_id, + event_id, + group_id, + flags, + data0, + data1, + data2, + data3, + data4, + ) == 0 + } + } + + pub fn request_reserved_key( + &self, + event_id: SIMCONNECT_CLIENT_EVENT_ID, + key_choice1: &str, + key_choice2: &str, + key_choice3: &str, + ) -> bool { + let k1 = cstring(key_choice1); + let k2 = cstring(key_choice2); + let k3 = cstring(key_choice3); + + unsafe { + SimConnect_RequestReservedKey( + self.handle, + event_id, + k1.as_ptr(), + k2.as_ptr(), + k3.as_ptr(), + ) == 0 + } + } + + // ==================== Input Events ==================== + + pub fn map_input_event_to_client_event( + &self, + group_id: SIMCONNECT_INPUT_GROUP_ID, + input_definition: &str, + down_event: SIMCONNECT_CLIENT_EVENT_ID, + down_return_value: DWORD, + up_event: SIMCONNECT_CLIENT_EVENT_ID, + up_return_value: DWORD, + maskable: bool, + ) -> bool { + let input = cstring(input_definition); + unsafe { + SimConnect_MapInputEventToClientEvent( + self.handle, + group_id, + input.as_ptr(), + down_event, + down_return_value, + up_event, + up_return_value, + maskable as i32, + ) == 0 + } + } + + pub fn map_input_event_to_client_event_ex1( + &self, + group_id: SIMCONNECT_INPUT_GROUP_ID, + input_definition: &str, + down_event: SIMCONNECT_CLIENT_EVENT_ID, + down_return_value: DWORD, + up_event: SIMCONNECT_CLIENT_EVENT_ID, + up_return_value: DWORD, + maskable: bool, + ) -> bool { + let input = cstring(input_definition); + unsafe { + SimConnect_MapInputEventToClientEvent_EX1( + self.handle, + group_id, + input.as_ptr(), + down_event, + down_return_value, + up_event, + up_return_value, + maskable as i32, + ) == 0 + } + } + + pub fn set_input_group_state(&self, group_id: SIMCONNECT_INPUT_GROUP_ID, state: DWORD) -> bool { + unsafe { SimConnect_SetInputGroupState(self.handle, group_id, state) == 0 } + } + + pub fn set_input_priority(&self, group_id: SIMCONNECT_INPUT_GROUP_ID, priority: DWORD) -> bool { + unsafe { SimConnect_SetInputGroupPriority(self.handle, group_id, priority) == 0 } + } + + pub fn remove_input_event( + &self, + group_id: SIMCONNECT_INPUT_GROUP_ID, + input_definition: &str, + ) -> bool { + let input = cstring(input_definition); + unsafe { + SimConnect_RemoveInputEvent(self.handle, group_id, input.as_ptr()) == 0 + } + } + + pub fn clear_input_group(&self, group_id: SIMCONNECT_INPUT_GROUP_ID) -> bool { + unsafe { SimConnect_ClearInputGroup(self.handle, group_id) == 0 } + } + + // ==================== Data Requests ==================== + + pub fn request_data_on_sim_object( + &self, + request_id: SIMCONNECT_DATA_REQUEST_ID, + define_id: SIMCONNECT_DATA_DEFINITION_ID, + object_id: SIMCONNECT_OBJECT_ID, + period: SIMCONNECT_PERIOD, + flags: SIMCONNECT_DATA_REQUEST_FLAG, + origin: DWORD, + interval: DWORD, + limit: DWORD, + ) -> bool { + unsafe { + SimConnect_RequestDataOnSimObject( + self.handle, + request_id, + define_id, + object_id, + period, + flags, + origin, + interval, + limit, + ) == 0 + } + } + + pub fn request_data_on_sim_object_type( + &self, + request_id: SIMCONNECT_DATA_REQUEST_ID, + define_id: SIMCONNECT_DATA_DEFINITION_ID, + radius_in_meters: DWORD, + object_type: SIMCONNECT_SIMOBJECT_TYPE, + ) -> bool { + unsafe { + SimConnect_RequestDataOnSimObjectType( + self.handle, + request_id, + define_id, + radius_in_meters, + object_type, + ) == 0 + } + } + + pub unsafe fn set_data_on_sim_object( + &self, + define_id: SIMCONNECT_DATA_DEFINITION_ID, + object_id: SIMCONNECT_OBJECT_ID, + flags: SIMCONNECT_DATA_SET_FLAG, + array_count: DWORD, + size: DWORD, + pntr: *mut std::os::raw::c_void, + ) -> bool { + unsafe { + SimConnect_SetDataOnSimObject( + self.handle, define_id, object_id, flags, array_count, size, pntr, + ) == 0 + } + } + + // ==================== Client Data ==================== + + pub fn create_client_data( + &self, + data_id: SIMCONNECT_CLIENT_DATA_ID, + size: DWORD, + flags: SIMCONNECT_CREATE_CLIENT_DATA_FLAG, + ) -> bool { + unsafe { SimConnect_CreateClientData(self.handle, data_id, size, flags) == 0 } + } + + pub fn map_client_data_name_to_id( + &self, + client_data_name: &str, + data_id: SIMCONNECT_CLIENT_DATA_ID, + ) -> bool { + let name = cstring(client_data_name); + unsafe { + SimConnect_MapClientDataNameToID(self.handle, name.as_ptr(), data_id) == 0 + } + } + + pub fn add_to_client_data_definition( + &self, + define_id: SIMCONNECT_DATA_DEFINITION_ID, + offset: DWORD, + size_or_type: DWORD, + epsilon: f32, + datum_id: DWORD, + ) -> bool { + unsafe { + SimConnect_AddToClientDataDefinition( + self.handle, define_id, offset, size_or_type, epsilon, datum_id, + ) == 0 + } + } + + pub fn clear_client_data_definition(&self, define_id: SIMCONNECT_DATA_DEFINITION_ID) -> bool { + unsafe { SimConnect_ClearClientDataDefinition(self.handle, define_id) == 0 } + } + + pub fn request_client_data( + &self, + data_id: SIMCONNECT_CLIENT_DATA_ID, + request_id: SIMCONNECT_DATA_REQUEST_ID, + define_id: SIMCONNECT_DATA_DEFINITION_ID, + period: SIMCONNECT_CLIENT_DATA_PERIOD, + flags: SIMCONNECT_CLIENT_DATA_REQUEST_FLAG, + origin: DWORD, + interval: DWORD, + limit: DWORD, + ) -> bool { + unsafe { + SimConnect_RequestClientData( + self.handle, + data_id, + request_id, + define_id, + period, + flags, + origin, + interval, + limit, + ) == 0 + } + } + + pub unsafe fn set_client_data( + &self, + data_id: SIMCONNECT_CLIENT_DATA_ID, + define_id: SIMCONNECT_DATA_DEFINITION_ID, + flags: DWORD, + reserved: DWORD, + unit_size: DWORD, + data_set: *mut std::os::raw::c_void, + ) -> bool { + unsafe { + SimConnect_SetClientData( + self.handle, data_id, define_id, flags, reserved, unit_size, data_set, + ) == 0 + } + } + + // ==================== AI Objects ==================== + + pub fn ai_create_parked_atc_aircraft( + &self, + container_title: &str, + tail_number: &str, + airport_id: &str, + request_id: SIMCONNECT_DATA_REQUEST_ID, + ) -> bool { + let title = cstring(container_title); + let tail = cstring(tail_number); + let airport = cstring(airport_id); + + unsafe { + SimConnect_AICreateParkedATCAircraft( + self.handle, + title.as_ptr(), + tail.as_ptr(), + airport.as_ptr(), + request_id, + ) == 0 + } + } + + pub fn ai_create_enroute_atc_aircraft( + &self, + container_title: &str, + tail_number: &str, + flight_number: i32, + flight_plan_path: &str, + flight_plan_position: f64, + touch_and_go: bool, + request_id: SIMCONNECT_DATA_REQUEST_ID, + ) -> bool { + let title = cstring(container_title); + let tail = cstring(tail_number); + let plan = cstring(flight_plan_path); + + unsafe { + SimConnect_AICreateEnrouteATCAircraft( + self.handle, + title.as_ptr(), + tail.as_ptr(), + flight_number, + plan.as_ptr(), + flight_plan_position, + touch_and_go as i32, + request_id, + ) == 0 + } + } + + pub fn ai_create_non_atc_aircraft( + &self, + container_title: &str, + tail_number: &str, + init_pos: SIMCONNECT_DATA_INITPOSITION, + request_id: SIMCONNECT_DATA_REQUEST_ID, + ) -> bool { + let title = cstring(container_title); + let tail = cstring(tail_number); + + unsafe { + SimConnect_AICreateNonATCAircraft( + self.handle, title.as_ptr(), tail.as_ptr(), init_pos, request_id, + ) == 0 + } + } + + pub fn ai_create_simulated_object( + &self, + container_title: &str, + init_pos: SIMCONNECT_DATA_INITPOSITION, + request_id: SIMCONNECT_DATA_REQUEST_ID, + ) -> bool { + let title = cstring(container_title); + unsafe { + SimConnect_AICreateSimulatedObject(self.handle, title.as_ptr(), init_pos, request_id) == 0 + } + } + + pub fn ai_release_control( + &self, + object_id: SIMCONNECT_OBJECT_ID, + request_id: SIMCONNECT_DATA_REQUEST_ID, + ) -> bool { + unsafe { SimConnect_AIReleaseControl(self.handle, object_id, request_id) == 0 } + } + + pub fn ai_remove_object( + &self, + object_id: SIMCONNECT_OBJECT_ID, + request_id: SIMCONNECT_DATA_REQUEST_ID, + ) -> bool { + unsafe { SimConnect_AIRemoveObject(self.handle, object_id, request_id) == 0 } + } + + pub fn ai_set_aircraft_flight_plan( + &self, + object_id: SIMCONNECT_OBJECT_ID, + flight_plan_path: &str, + request_id: SIMCONNECT_DATA_REQUEST_ID, + ) -> bool { + let plan = cstring(flight_plan_path); + unsafe { + SimConnect_AISetAircraftFlightPlan( + self.handle, object_id, plan.as_ptr(), request_id, + ) == 0 + } + } + + // ==================== Weather ==================== + + pub fn weather_request_interpolated_observation( + &self, + request_id: SIMCONNECT_DATA_REQUEST_ID, + lat: f32, + lon: f32, + alt: f32, + ) -> bool { + unsafe { + SimConnect_WeatherRequestInterpolatedObservation(self.handle, request_id, lat, lon, alt) == 0 + } + } + + pub fn weather_request_observation_at_station( + &self, + request_id: SIMCONNECT_DATA_REQUEST_ID, + station: &str, + ) -> bool { + let station = cstring(station); + unsafe { + SimConnect_WeatherRequestObservationAtStation(self.handle, request_id, station.as_ptr()) == 0 + } + } + + pub fn weather_request_observation_at_nearest_station( + &self, + request_id: SIMCONNECT_DATA_REQUEST_ID, + lat: f32, + lon: f32, + ) -> bool { + unsafe { + SimConnect_WeatherRequestObservationAtNearestStation(self.handle, request_id, lat, lon) == 0 + } + } + + pub fn weather_create_station( + &self, + request_id: SIMCONNECT_DATA_REQUEST_ID, + icao: &str, + name: &str, + lat: f32, + lon: f32, + alt: f32, + ) -> bool { + let icao_c = cstring(icao); + let name_c = cstring(name); + + unsafe { + SimConnect_WeatherCreateStation( + self.handle, + request_id, + icao_c.as_ptr(), + name_c.as_ptr(), + lat, + lon, + alt, + ) == 0 + } + } + + pub fn weather_remove_station(&self, request_id: SIMCONNECT_DATA_REQUEST_ID, station: &str) -> bool { + let station = cstring(station); + unsafe { + SimConnect_WeatherRemoveStation(self.handle, request_id, station.as_ptr()) == 0 + } + } + + pub fn weather_set_observation(&self, seconds: DWORD, observation: &str) -> bool { + let obs = cstring(observation); + unsafe { + SimConnect_WeatherSetObservation(self.handle, seconds, obs.as_ptr()) == 0 + } + } + + pub fn weather_set_mode_server(&self, port: DWORD, seconds: DWORD) -> bool { + unsafe { SimConnect_WeatherSetModeServer(self.handle, port, seconds) == 0 } + } + + pub fn weather_set_mode_theme(&self, theme_name: &str) -> bool { + let theme = cstring(theme_name); + unsafe { SimConnect_WeatherSetModeTheme(self.handle, theme.as_ptr()) == 0 } + } + + pub fn weather_set_mode_global(&self) -> bool { + unsafe { SimConnect_WeatherSetModeGlobal(self.handle) == 0 } + } + + pub fn weather_set_mode_custom(&self) -> bool { + unsafe { SimConnect_WeatherSetModeCustom(self.handle) == 0 } + } + + pub fn weather_set_dynamic_update_rate(&self, rate: DWORD) -> bool { + unsafe { SimConnect_WeatherSetDynamicUpdateRate(self.handle, rate) == 0 } + } + + pub fn weather_request_cloud_state( + &self, + request_id: SIMCONNECT_DATA_REQUEST_ID, + min_x: f32, + min_y: f32, + min_z: f32, + max_x: f32, + max_y: f32, + max_z: f32, + flags: DWORD, + ) -> bool { + unsafe { + SimConnect_WeatherRequestCloudState( + self.handle, request_id, min_x, min_y, min_z, max_x, max_y, max_z, flags, + ) == 0 + } + } + + pub fn weather_create_thermal( + &self, + request_id: SIMCONNECT_DATA_REQUEST_ID, + lat: f32, + lon: f32, + alt: f32, + radius: f32, + height: f32, + core_rate: f32, + core_turbulence: f32, + sink_rate: f32, + sink_turbulence: f32, + core_size: f32, + core_transition_size: f32, + sink_layer_size: f32, + sink_transition_size: f32, + ) -> bool { + unsafe { + SimConnect_WeatherCreateThermal( + self.handle, + request_id, + lat, + lon, + alt, + radius, + height, + core_rate, + core_turbulence, + sink_rate, + sink_turbulence, + core_size, + core_transition_size, + sink_layer_size, + sink_transition_size, + ) == 0 + } + } + + pub fn weather_remove_thermal(&self, object_id: SIMCONNECT_OBJECT_ID) -> bool { + unsafe { SimConnect_WeatherRemoveThermal(self.handle, object_id) == 0 } + } + + // ==================== Mission & System ==================== + + pub fn execute_mission_action(&self, instance_id: GUID) -> bool { + unsafe { SimConnect_ExecuteMissionAction(self.handle, instance_id) == 0 } + } + + pub fn complete_custom_mission_action(&self, instance_id: GUID) -> bool { + unsafe { SimConnect_CompleteCustomMissionAction(self.handle, instance_id) == 0 } + } + + pub fn request_system_state(&self, request_id: SIMCONNECT_DATA_REQUEST_ID, state: &str) -> bool { + let state = cstring(state); + unsafe { SimConnect_RequestSystemState(self.handle, request_id, state.as_ptr()) == 0 } + } + + pub fn set_system_state(&self, state: &str, integer: DWORD, float_val: f32, string_val: &str) -> bool { + let state_c = cstring(state); + let string_c = cstring(string_val); + + unsafe { + SimConnect_SetSystemState( + self.handle, + state_c.as_ptr(), + integer, + float_val, + string_c.as_ptr(), + ) == 0 + } + } + + pub fn flight_load(&self, file_name: &str) -> bool { + let name = cstring(file_name); + unsafe { SimConnect_FlightLoad(self.handle, name.as_ptr()) == 0 } + } + + pub fn flight_save(&self, file_name: &str, title: &str, description: &str, flags: DWORD) -> bool { + let name = cstring(file_name); + let t = cstring(title); + let d = cstring(description); + unsafe { SimConnect_FlightSave(self.handle, name.as_ptr(), t.as_ptr(), d.as_ptr(), flags) == 0 } + } + + pub fn flight_plan_load(&self, file_name: &str) -> bool { + let name = cstring(file_name); + unsafe { SimConnect_FlightPlanLoad(self.handle, name.as_ptr()) == 0 } + } + + // ==================== Facilities ==================== + + pub fn subscribe_to_facilities( + &self, + list_type: SIMCONNECT_FACILITY_LIST_TYPE, + request_id: SIMCONNECT_DATA_REQUEST_ID, + ) -> bool { + unsafe { SimConnect_SubscribeToFacilities(self.handle, list_type, request_id) == 0 } + } + + pub fn unsubscribe_to_facilities(&self, list_type: SIMCONNECT_FACILITY_LIST_TYPE) -> bool { + unsafe { SimConnect_UnsubscribeToFacilities(self.handle, list_type) == 0 } + } + + pub fn request_facilities_list( + &self, + list_type: SIMCONNECT_FACILITY_LIST_TYPE, + request_id: SIMCONNECT_DATA_REQUEST_ID, + ) -> bool { + unsafe { SimConnect_RequestFacilitiesList(self.handle, list_type, request_id) == 0 } + } + + pub fn add_to_facility_definition(&self, define_id: SIMCONNECT_DATA_DEFINITION_ID, field_name: &str) -> bool { + let field = cstring(field_name); + unsafe { SimConnect_AddToFacilityDefinition(self.handle, define_id, field.as_ptr()) == 0 } + } + + pub fn request_facility_data( + &self, + define_id: SIMCONNECT_DATA_DEFINITION_ID, + request_id: SIMCONNECT_DATA_REQUEST_ID, + icao: &str, + region: Option<&str>, + ) -> bool { + let icao = cstring(icao); + let region = region.map(|s| cstring(s)); + unsafe { + SimConnect_RequestFacilityData( + self.handle, + define_id, + request_id, + icao.as_ptr(), + region.as_ref().map_or(ptr::null(), |s| s.as_ptr()), + ) == 0 + } + } + + pub fn subscribe_to_facilities_ex1( + &self, + list_type: SIMCONNECT_FACILITY_LIST_TYPE, + new_in_range_request_id: SIMCONNECT_DATA_REQUEST_ID, + old_out_of_range_request_id: SIMCONNECT_DATA_REQUEST_ID, + ) -> bool { + unsafe { + SimConnect_SubscribeToFacilities_EX1( + self.handle, + list_type, + new_in_range_request_id, + old_out_of_range_request_id, + ) == 0 + } + } + + pub fn unsubscribe_to_facilities_ex1( + &self, + list_type: SIMCONNECT_FACILITY_LIST_TYPE, + unsubscribe_new_in_range: bool, + unsubscribe_old_out_of_range: bool, + ) -> bool { + unsafe { + SimConnect_UnsubscribeToFacilities_EX1( + self.handle, + list_type, + unsubscribe_new_in_range, + unsubscribe_old_out_of_range, + ) == 0 + } + } + + pub fn request_facilities_list_ex1( + &self, + list_type: SIMCONNECT_FACILITY_LIST_TYPE, + request_id: SIMCONNECT_DATA_REQUEST_ID, + ) -> bool { + unsafe { + SimConnect_RequestFacilitiesList_EX1(self.handle, list_type, request_id) == 0 + } + } + + pub fn request_facility_data_ex1( + &self, + define_id: SIMCONNECT_DATA_DEFINITION_ID, + request_id: SIMCONNECT_DATA_REQUEST_ID, + icao: &str, + region: Option<&str>, + type_: Option, + ) -> bool { + let icao = cstring(icao); + let region = region.map(|s| cstring(s)); + unsafe { + SimConnect_RequestFacilityData_EX1( + self.handle, + define_id, + request_id, + icao.as_ptr(), + region.as_ref().map_or(ptr::null(), |s| s.as_ptr()), + type_.unwrap_or(0) as ::std::os::raw::c_char, + ) == 0 + } + } + + pub unsafe fn request_jetway_data( + &self, + airport_icao: &str, + array_count: DWORD, + indexes: *mut i32, + ) -> bool { + let icao = cstring(airport_icao); + unsafe { + SimConnect_RequestJetwayData(self.handle, icao.as_ptr(), array_count, indexes) == 0 + } + } + + pub fn add_facility_data_definition_filter( + &self, + define_id: SIMCONNECT_DATA_DEFINITION_ID, + filter_path: &str, + filter_data: *const std::os::raw::c_void, + cb_unit_size: DWORD, + ) -> bool { + let path = cstring(filter_path); + unsafe { + SimConnect_AddFacilityDataDefinitionFilter( + self.handle, + define_id, + path.as_ptr(), + cb_unit_size, + filter_data as *mut _, + ) == 0 + } + } + + pub fn clear_all_facility_data_definition_filters( + &self, + define_id: SIMCONNECT_DATA_DEFINITION_ID, + ) -> bool { + unsafe { + SimConnect_ClearAllFacilityDataDefinitionFilters(self.handle, define_id) == 0 + } + } + + // ==================== Camera ==================== + + pub fn camera_set_relative_6dof( + &self, + delta_x: f32, + delta_y: f32, + delta_z: f32, + pitch: f32, + bank: f32, + heading: f32, + ) -> bool { + unsafe { + SimConnect_CameraSetRelative6DOF( + self.handle, delta_x, delta_y, delta_z, pitch, bank, heading, + ) == 0 + } + } + + // ==================== Menu ==================== + + pub fn menu_add_item( + &self, + menu_item: &str, + event_id: SIMCONNECT_CLIENT_EVENT_ID, + data: DWORD, + ) -> bool { + let item = cstring(menu_item); + unsafe { SimConnect_MenuAddItem(self.handle, item.as_ptr(), event_id, data) == 0 } + } + + pub fn menu_add_sub_item( + &self, + menu_event_id: SIMCONNECT_CLIENT_EVENT_ID, + menu_item: &str, + sub_menu_event_id: SIMCONNECT_CLIENT_EVENT_ID, + data: DWORD, + ) -> bool { + let item = cstring(menu_item); + unsafe { + SimConnect_MenuAddSubItem(self.handle, menu_event_id, item.as_ptr(), sub_menu_event_id, data) == 0 + } + } + + pub fn menu_delete_item(&self, event_id: SIMCONNECT_CLIENT_EVENT_ID) -> bool { + unsafe { SimConnect_MenuDeleteItem(self.handle, event_id) == 0 } + } + + pub fn menu_delete_sub_item( + &self, + event_id: SIMCONNECT_CLIENT_EVENT_ID, + sub_event_id: SIMCONNECT_CLIENT_EVENT_ID, + ) -> bool { + unsafe { SimConnect_MenuDeleteSubItem(self.handle, event_id, sub_event_id) == 0 } + } + + // ==================== Other ==================== + + pub fn enumerate_controllers(&self) -> bool { + unsafe { SimConnect_EnumerateControllers(self.handle) == 0 } + } + + pub fn enumerate_input_events(&self, request_id: SIMCONNECT_DATA_REQUEST_ID) -> bool { + unsafe { SimConnect_EnumerateInputEvents(self.handle, request_id) == 0 } + } + + pub fn get_input_event(&self, request_id: SIMCONNECT_DATA_REQUEST_ID, hash: u64) -> bool { + unsafe { SimConnect_GetInputEvent(self.handle, request_id, hash) == 0 } + } + + pub unsafe fn set_input_event( + &self, + hash: u64, + unit_size: DWORD, + value: *mut std::os::raw::c_void, + ) -> bool { + unsafe { SimConnect_SetInputEvent(self.handle, hash, unit_size, value) == 0 } + } + + pub fn subscribe_input_event(&self, hash: u64) -> bool { + unsafe { SimConnect_SubscribeInputEvent(self.handle, hash) == 0 } + } + + pub fn unsubscribe_input_event(&self, hash: u64) -> bool { + unsafe { SimConnect_UnsubscribeInputEvent(self.handle, hash) == 0 } + } + + pub fn enumerate_input_event_params(&self, hash: u64) -> bool { + unsafe { SimConnect_EnumerateInputEventParams(self.handle, hash) == 0 } + } + + pub unsafe fn execute_action( + &self, + request_id: DWORD, + action_id: &str, + unit_size: DWORD, + param_values: *mut std::os::raw::c_void, + ) -> bool { + let action = cstring(action_id); + unsafe { + SimConnect_ExecuteAction(self.handle, request_id, action.as_ptr(), unit_size, param_values) == 0 + } + } + + pub unsafe fn text( + &self, + text_type: SIMCONNECT_TEXT_TYPE, + time_in_seconds: f32, + event_id: SIMCONNECT_CLIENT_EVENT_ID, + unit_size: DWORD, + data_set: *mut std::os::raw::c_void, + ) -> bool { + unsafe { + SimConnect_Text(self.handle, text_type, time_in_seconds, event_id, unit_size, data_set) == 0 + } + } + + pub unsafe fn get_last_sent_packet_id(&self, error: *mut DWORD) -> bool { + unsafe { SimConnect_GetLastSentPacketID(self.handle, error) == 0 } + } + + pub unsafe fn call_dispatch( + &self, + dispatch_callback: DispatchProc, + context: *mut std::os::raw::c_void, + ) -> bool { + unsafe { SimConnect_CallDispatch(self.handle, dispatch_callback, context) == 0 } + } + + pub unsafe fn request_response_times(&self, count: DWORD, elapsed_seconds: *mut f32) -> bool { + unsafe { SimConnect_RequestResponseTimes(self.handle, count, elapsed_seconds) == 0 } + } + + // ==================== String Utilities ==================== + + pub unsafe fn retrieve_string( + p_data: *mut SIMCONNECT_RECV, + cb_data: DWORD, + p_string_v: *mut std::os::raw::c_void, + psz_string: *mut *mut std::os::raw::c_char, + pcb_string: *mut DWORD, + ) -> bool { + unsafe { + SimConnect_RetrieveString(p_data, cb_data, p_string_v, psz_string, pcb_string) == 0 + } + } + + pub unsafe fn insert_string( + p_dest: *mut std::os::raw::c_char, + cb_dest: DWORD, + pp_end: *mut *mut std::os::raw::c_void, + pcb_string: *mut DWORD, + p_source: *const std::os::raw::c_char, + ) -> bool { + unsafe { + SimConnect_InsertString(p_dest, cb_dest, pp_end, pcb_string, p_source) == 0 + } + } + + // ==================== Main Message Loop ==================== + + pub fn get_next_message(&self) -> Result, &str> { + unsafe { + let mut data_buf: *mut SIMCONNECT_RECV = ptr::null_mut(); + let mut size_buf: DWORD = 0; + + if SimConnect_GetNextDispatch(self.handle, &mut data_buf, &mut size_buf) != 0 { + return Err("Failed getting data from SimConnect"); + } + + if data_buf.is_null() { + return Ok(DispatchResult::Null); + } + + match (*data_buf).dwID as SIMCONNECT_RECV_ID { + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_NULL => Ok(DispatchResult::Null), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EXCEPTION => Ok(DispatchResult::Exception(&*(data_buf as *const SIMCONNECT_RECV_EXCEPTION))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_OPEN => Ok(DispatchResult::Open(&*(data_buf as *const SIMCONNECT_RECV_OPEN))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_QUIT => Ok(DispatchResult::Quit(&*(data_buf as *const SIMCONNECT_RECV_QUIT))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT => Ok(DispatchResult::Event(&*(data_buf as *const SIMCONNECT_RECV_EVENT))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_OBJECT_ADDREMOVE => Ok(DispatchResult::EventObjectAddRemove(&*(data_buf as *const SIMCONNECT_RECV_EVENT_OBJECT_ADDREMOVE))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_FILENAME => Ok(DispatchResult::EventFilename(&*(data_buf as *const SIMCONNECT_RECV_EVENT_FILENAME))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_FRAME => Ok(DispatchResult::EventFrame(&*(data_buf as *const SIMCONNECT_RECV_EVENT_FRAME))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_SIMOBJECT_DATA => Ok(DispatchResult::SimObjectData(&*(data_buf as *const SIMCONNECT_RECV_SIMOBJECT_DATA))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_SIMOBJECT_DATA_BYTYPE => Ok(DispatchResult::SimObjectDataByType(&*(data_buf as *const SIMCONNECT_RECV_SIMOBJECT_DATA_BYTYPE))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_WEATHER_OBSERVATION => Ok(DispatchResult::WeatherObservation(&*(data_buf as *const SIMCONNECT_RECV_WEATHER_OBSERVATION))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_CLOUD_STATE => Ok(DispatchResult::CloudState(&*(data_buf as *const SIMCONNECT_RECV_CLOUD_STATE))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_ASSIGNED_OBJECT_ID => Ok(DispatchResult::AssignedObjectId(&*(data_buf as *const SIMCONNECT_RECV_ASSIGNED_OBJECT_ID))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_RESERVED_KEY => Ok(DispatchResult::ReservedKey(&*(data_buf as *const SIMCONNECT_RECV_RESERVED_KEY))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_CUSTOM_ACTION => Ok(DispatchResult::CustomAction(&*(data_buf as *const SIMCONNECT_RECV_CUSTOM_ACTION))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_SYSTEM_STATE => Ok(DispatchResult::SystemState(&*(data_buf as *const SIMCONNECT_RECV_SYSTEM_STATE))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_CLIENT_DATA => Ok(DispatchResult::ClientData(&*(data_buf as *const SIMCONNECT_RECV_CLIENT_DATA))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_WEATHER_MODE => Ok(DispatchResult::EventWeatherMode(&*(data_buf as *const SIMCONNECT_RECV_EVENT_WEATHER_MODE))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_AIRPORT_LIST => Ok(DispatchResult::AirportList(&*(data_buf as *const SIMCONNECT_RECV_AIRPORT_LIST))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_VOR_LIST => Ok(DispatchResult::VorList(&*(data_buf as *const SIMCONNECT_RECV_VOR_LIST))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_NDB_LIST => Ok(DispatchResult::NdbList(&*(data_buf as *const SIMCONNECT_RECV_NDB_LIST))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_WAYPOINT_LIST => Ok(DispatchResult::WaypointList(&*(data_buf as *const SIMCONNECT_RECV_WAYPOINT_LIST))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_MULTIPLAYER_SERVER_STARTED => Ok(DispatchResult::EventMultiplayerServerStarted(&*(data_buf as *const SIMCONNECT_RECV_EVENT_MULTIPLAYER_SERVER_STARTED))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_MULTIPLAYER_CLIENT_STARTED => Ok(DispatchResult::EventMultiplayerClientStarted(&*(data_buf as *const SIMCONNECT_RECV_EVENT_MULTIPLAYER_CLIENT_STARTED))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_MULTIPLAYER_SESSION_ENDED => Ok(DispatchResult::EventMultiplayerSessionEnded(&*(data_buf as *const SIMCONNECT_RECV_EVENT_MULTIPLAYER_SESSION_ENDED))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_RACE_END => Ok(DispatchResult::EventRaceEnd(&*(data_buf as *const SIMCONNECT_RECV_EVENT_RACE_END))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_RACE_LAP => Ok(DispatchResult::EventRaceLap(&*(data_buf as *const SIMCONNECT_RECV_EVENT_RACE_LAP))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_EX1 => Ok(DispatchResult::EventEx1(&*(data_buf as *const SIMCONNECT_RECV_EVENT_EX1))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_FACILITY_DATA => Ok(DispatchResult::FacilityData(&*(data_buf as *const SIMCONNECT_RECV_FACILITY_DATA))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_FACILITY_DATA_END => Ok(DispatchResult::FacilityDataEnd(&*(data_buf as *const SIMCONNECT_RECV_FACILITY_DATA_END))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_FACILITY_MINIMAL_LIST => Ok(DispatchResult::FacilityMinimalList(&*(data_buf as *const SIMCONNECT_RECV_FACILITY_MINIMAL_LIST))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_JETWAY_DATA => Ok(DispatchResult::JetwayData(&*(data_buf as *const SIMCONNECT_RECV_JETWAY_DATA))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_ACTION_CALLBACK => Ok(DispatchResult::ActionCallback(&*(data_buf as *const SIMCONNECT_RECV_ACTION_CALLBACK))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_ENUMERATE_INPUT_EVENTS => Ok(DispatchResult::EnumerateInputEvents(&*(data_buf as *const SIMCONNECT_RECV_ENUMERATE_INPUT_EVENTS))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_GET_INPUT_EVENT => Ok(DispatchResult::GetInputEvent(&*(data_buf as *const SIMCONNECT_RECV_GET_INPUT_EVENT))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_SUBSCRIBE_INPUT_EVENT => Ok(DispatchResult::SubscribeInputEvent(&*(data_buf as *const SIMCONNECT_RECV_SUBSCRIBE_INPUT_EVENT))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_ENUMERATE_INPUT_EVENT_PARAMS => Ok(DispatchResult::EnumerateInputEventParams(&*(data_buf as *const SIMCONNECT_RECV_ENUMERATE_INPUT_EVENT_PARAMS))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_CONTROLLERS_LIST => Ok(DispatchResult::ControllersList(&*(data_buf as *const SIMCONNECT_RECV_CONTROLLERS_LIST))), + _ => Err("Unhandled RECV_ID"), + } + } + } +} + +impl Drop for SimConnector { + fn drop(&mut self) { + if !self.handle.is_null() { + let _ = self.close(); + } + } +} + +#[inline] +fn cstring(s: &str) -> CString { + CString::new(s).expect("string contained interior nul byte") +} diff --git a/simulators/FS2024/Cargo.toml b/simulators/FS2024/Cargo.toml new file mode 100644 index 0000000..78c459b --- /dev/null +++ b/simulators/FS2024/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "simconnect-fs2024" +license = "MIT" +description = "Rust bindings for SimConnect" +version = "0.5.0" +authors = ["Connor T"] +edition = "2021" + +[build-dependencies] +bindgen = "0.72" diff --git a/simulators/FS2024/SimConnect.dll b/simulators/FS2024/SimConnect.dll new file mode 100644 index 0000000..8c4209c Binary files /dev/null and b/simulators/FS2024/SimConnect.dll differ diff --git a/simulators/FS2024/build.rs b/simulators/FS2024/build.rs new file mode 100644 index 0000000..a8ebde3 --- /dev/null +++ b/simulators/FS2024/build.rs @@ -0,0 +1,361 @@ +use std::{env, path::PathBuf}; + +fn main() { + let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); + let lib_dir = PathBuf::from(manifest_dir).join("libsrc").join("lib"); + + println!("cargo:rustc-link-search={}", lib_dir.display()); + println!("cargo:rustc-link-lib=static=SimConnect"); + + let handle = std::thread::Builder::new() + .stack_size(128 * 1024 * 1024) + .spawn(|| { + let mut builder = bindgen::Builder::default() + .header("libsrc/include/SimConnect.hpp") + .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) + .impl_debug(true); + + // ==================== CONSTANTS / VARS ==================== + let vars = [ + "SIMCONNECT_UNUSED", + "SIMCONNECT_OBJECT_ID_USER", + "SIMCONNECT_OBJECT_ID_MAX", + "SIMCONNECT_OBJECT_ID_USER_AIRCRAFT", + "SIMCONNECT_OBJECT_ID_USER_AVATAR", + "SIMCONNECT_OBJECT_ID_USER_CURRENT", + "SIMCONNECT_CAMERA_IGNORE_FIELD", + "SIMCONNECT_CLIENTDATA_MAX_SIZE", + "SIMCONNECT_GROUP_PRIORITY_HIGHEST", + "SIMCONNECT_GROUP_PRIORITY_HIGHEST_MASKABLE", + "SIMCONNECT_GROUP_PRIORITY_STANDARD", + "SIMCONNECT_GROUP_PRIORITY_DEFAULT", + "SIMCONNECT_GROUP_PRIORITY_LOWEST", + "MAX_METAR_LENGTH", + "MAX_THERMAL_SIZE", + "MAX_THERMAL_RATE", + "INITPOSITION_AIRSPEED_CRUISE", + "INITPOSITION_AIRSPEED_KEEP", + "SIMCONNECT_CLIENTDATATYPE_INT8", + "SIMCONNECT_CLIENTDATATYPE_INT16", + "SIMCONNECT_CLIENTDATATYPE_INT32", + "SIMCONNECT_CLIENTDATATYPE_INT64", + "SIMCONNECT_CLIENTDATATYPE_FLOAT32", + "SIMCONNECT_CLIENTDATATYPE_FLOAT64", + "SIMCONNECT_CLIENTDATAOFFSET_AUTO", + "SIMCONNECT_OPEN_CONFIGINDEX_LOCAL", + "SIMCONNECT_RECV_ID_VOR_LIST_HAS_NAV_SIGNAL", + "SIMCONNECT_RECV_ID_VOR_LIST_HAS_LOCALIZER", + "SIMCONNECT_RECV_ID_VOR_LIST_HAS_GLIDE_SLOPE", + "SIMCONNECT_RECV_ID_VOR_LIST_HAS_DME", + "SIMCONNECT_WAYPOINT_NONE", + "SIMCONNECT_WAYPOINT_SPEED_REQUESTED", + "SIMCONNECT_WAYPOINT_THROTTLE_REQUESTED", + "SIMCONNECT_WAYPOINT_COMPUTE_VERTICAL_SPEED", + "SIMCONNECT_WAYPOINT_ALTITUDE_IS_AGL", + "SIMCONNECT_WAYPOINT_ON_GROUND", + "SIMCONNECT_WAYPOINT_REVERSE", + "SIMCONNECT_WAYPOINT_WRAP_TO_FIRST", + "SIMCONNECT_WAYPOINT_ALWAYS_BACKUP", + "SIMCONNECT_WAYPOINT_KEEP_LAST_HEADING", + "SIMCONNECT_WAYPOINT_YIELD_TO_USER", + "SIMCONNECT_WAYPOINT_CAN_REVERSE", + "SIMCONNECT_EVENT_FLAG_DEFAULT", + "SIMCONNECT_EVENT_FLAG_FAST_REPEAT_TIMER", + "SIMCONNECT_EVENT_FLAG_SLOW_REPEAT_TIMER", + "SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY", + "SIMCONNECT_DATA_REQUEST_FLAG_DEFAULT", + "SIMCONNECT_DATA_REQUEST_FLAG_CHANGED", + "SIMCONNECT_DATA_REQUEST_FLAG_TAGGED", + "SIMCONNECT_DATA_SET_FLAG_DEFAULT", + "SIMCONNECT_DATA_SET_FLAG_TAGGED", + "SIMCONNECT_CREATE_CLIENT_DATA_FLAG_DEFAULT", + "SIMCONNECT_CREATE_CLIENT_DATA_FLAG_READ_ONLY", + "SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_DEFAULT", + "SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_CHANGED", + "SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_TAGGED", + "SIMCONNECT_CLIENT_DATA_SET_FLAG_DEFAULT", + "SIMCONNECT_CLIENT_DATA_SET_FLAG_TAGGED", + "SIMCONNECT_VIEW_SYSTEM_EVENT_DATA_COCKPIT_2D", + "SIMCONNECT_VIEW_SYSTEM_EVENT_DATA_COCKPIT_VIRTUAL", + "SIMCONNECT_VIEW_SYSTEM_EVENT_DATA_ORTHOGONAL", + "SIMCONNECT_SOUND_SYSTEM_EVENT_DATA_MASTER", + "UNKNOWN_SENDID", + "UNKNOWN_INDEX", + "UNKNOWN_GROUP", + "SIMCONNECT_CLOUD_STATE_ARRAY_WIDTH", + "SIMCONNECT_CLOUD_STATE_ARRAY_SIZE", + "SIMCONNECT_COMM_BUS_BROADCAST_TO_JS", + "SIMCONNECT_COMM_BUS_BROADCAST_TO_WASM", + "SIMCONNECT_COMM_BUS_BROADCAST_TO_SIMCONNECT", + "SIMCONNECT_COMM_BUS_BROADCAST_TO_SIMCONNECT_SELF_CALL", + "SIMCONNECT_COMM_BUS_BROADCAST_TO_DEFAULT", + "SIMCONNECT_COMM_BUS_BROADCAST_TO_ALL_SIMCONNECT", + "SIMCONNECT_COMM_BUS_BROADCAST_TO_ALL", + "SIMCONNECT_CAMERA_DATA_MASK_NONE", + "SIMCONNECT_CAMERA_DATA_MASK_POSITION", + "SIMCONNECT_CAMERA_DATA_MASK_ROTATION", + "SIMCONNECT_CAMERA_DATA_MASK_TARGETED", + "SIMCONNECT_CAMERA_DATA_MASK_FOV", + "SIMCONNECT_CAMERA_DATA_MASK_ALL_ROTATION", + "SIMCONNECT_CAMERA_DATA_MASK_ALL_TARGETED", + "SIMCONNECT_CAMERA_FLAG_INTERACTION", + "SIMCONNECT_CAMERA_FLAG_ABOVE_GROUND", + ]; + + for v in vars { + builder = builder.allowlist_var(v); + } + + // ==================== TYPES / ENUMS ==================== + let types = [ + "HANDLE", + "SIMCONNECT_RECV_ID", + "SIMCONNECT_DATATYPE", + "SIMCONNECT_EXCEPTION", + "SIMCONNECT_SIMOBJECT_TYPE", + "SIMCONNECT_STATE", + "SIMCONNECT_PERIOD", + "SIMCONNECT_MISSION_END", + "SIMCONNECT_CLIENT_DATA_PERIOD", + "SIMCONNECT_TEXT_TYPE", + "SIMCONNECT_TEXT_RESULT", + "SIMCONNECT_WEATHER_MODE", + "SIMCONNECT_FACILITY_LIST_TYPE", + "SIMCONNECT_FACILITY_DATA_TYPE", + "SIMCONNECT_INPUT_EVENT_TYPE", + "SIMCONNECT_VOR_FLAGS", + "SIMCONNECT_WAYPOINT_FLAGS", + "SIMCONNECT_EVENT_FLAG", + "SIMCONNECT_DATA_REQUEST_FLAG", + "SIMCONNECT_DATA_SET_FLAG", + "SIMCONNECT_CREATE_CLIENT_DATA_FLAG", + "SIMCONNECT_CLIENT_DATA_REQUEST_FLAG", + "SIMCONNECT_CLIENT_DATA_SET_FLAG", + "SIMCONNECT_VIEW_SYSTEM_EVENT_DATA", + "SIMCONNECT_SOUND_SYSTEM_EVENT_DATA", + "SIMCONNECT_FLOW_EVENT", + "SIMCONNECT_POSITION_REFERENTIAL", + "SIMCONNECT_COMM_BUS_BROADCAST_TO", + "SIMCONNECT_CAMERA_DATA_MASK", + "SIMCONNECT_CAMERA_FLAG", + "SIMCONNECT_CAMERA_WORLD_LOCKER_STATUS", + "SIMCONNECT_CAMERA_AVAILABILITY", + ]; + + for t in types { + builder = builder.allowlist_type(t); + } + + // ==================== STRUCTS ==================== + let structs = [ + "SIMCONNECT_RECV", + "SIMCONNECT_RECV_EXCEPTION", + "SIMCONNECT_RECV_OPEN", + "SIMCONNECT_RECV_QUIT", + "SIMCONNECT_RECV_EVENT", + "SIMCONNECT_RECV_EVENT_FILENAME", + "SIMCONNECT_RECV_EVENT_OBJECT_ADDREMOVE", + "SIMCONNECT_RECV_EVENT_FRAME", + "SIMCONNECT_RECV_EVENT_MULTIPLAYER_SERVER_STARTED", + "SIMCONNECT_RECV_EVENT_MULTIPLAYER_CLIENT_STARTED", + "SIMCONNECT_RECV_EVENT_MULTIPLAYER_SESSION_ENDED", + "SIMCONNECT_RECV_EVENT_RACE_END", + "SIMCONNECT_RECV_EVENT_RACE_LAP", + "SIMCONNECT_RECV_SIMOBJECT_DATA", + "SIMCONNECT_RECV_SIMOBJECT_DATA_BYTYPE", + "SIMCONNECT_RECV_CLIENT_DATA", + "SIMCONNECT_RECV_WEATHER_OBSERVATION", + "SIMCONNECT_RECV_CLOUD_STATE", + "SIMCONNECT_RECV_ASSIGNED_OBJECT_ID", + "SIMCONNECT_RECV_RESERVED_KEY", + "SIMCONNECT_RECV_SYSTEM_STATE", + "SIMCONNECT_RECV_CUSTOM_ACTION", + "SIMCONNECT_RECV_EVENT_WEATHER_MODE", + "SIMCONNECT_RECV_FACILITIES_LIST", + "SIMCONNECT_DATA_FACILITY_AIRPORT", + "SIMCONNECT_RECV_AIRPORT_LIST", + "SIMCONNECT_DATA_FACILITY_WAYPOINT", + "SIMCONNECT_RECV_WAYPOINT_LIST", + "SIMCONNECT_DATA_FACILITY_NDB", + "SIMCONNECT_RECV_NDB_LIST", + "SIMCONNECT_DATA_FACILITY_VOR", + "SIMCONNECT_RECV_VOR_LIST", + "SIMCONNECT_RECV_EVENT_EX1", + "SIMCONNECT_DATA_RACE_RESULT", + "SIMCONNECT_RECV_FACILITY_DATA", + "SIMCONNECT_RECV_FACILITY_DATA_END", + "SIMCONNECT_ICAO", + "SIMCONNECT_FACILITY_MINIMAL", + "SIMCONNECT_RECV_FACILITY_MINIMAL_LIST", + "SIMCONNECT_DATA_PBH", + "SIMCONNECT_JETWAY_DATA", + "SIMCONNECT_RECV_JETWAY_DATA", + "SIMCONNECT_RECV_ACTION_CALLBACK", + "SIMCONNECT_INPUT_EVENT_DESCRIPTOR", + "SIMCONNECT_RECV_ENUMERATE_INPUT_EVENTS", + "SIMCONNECT_RECV_GET_INPUT_EVENT", + "SIMCONNECT_RECV_SUBSCRIBE_INPUT_EVENT", + "SIMCONNECT_RECV_ENUMERATE_INPUT_EVENT_PARAMS", + "SIMCONNECT_VERSION_BASE_TYPE", + "SIMCONNECT_CONTROLLER_ITEM", + "SIMCONNECT_RECV_CONTROLLERS_LIST", + "SIMCONNECT_RECV_LIST_TEMPLATE", + "SIMCONNECT_DATA_INITPOSITION", + "SIMCONNECT_DATA_MARKERSTATE", + "SIMCONNECT_DATA_WAYPOINT", + "SIMCONNECT_DATA_LATLONALT", + "SIMCONNECT_DATA_XYZ", + "SIMCONNECT_DATA_CAMERA", + "SIMCONNECT_RECV_CAMERA_DATA", + "SIMCONNECT_RECV_CAMERA_WORLD_LOCKER", + "SIMCONNECT_RECV_CAMERA_STATUS", + "SIMCONNECT_ENUMERATE_SIMOBJECT_LIVERY", + "SIMCONNECT_RECV_ENUMERATE_SIMOBJECT_AND_LIVERY_LIST", + "SIMCONNECT_RECV_FLOW_EVENT", + "SIMCONNECT_CAMERA_DEFINITION_ITEM", + "SIMCONNECT_RECV_CAMERA_DEFINITION_LIST", + "SIMCONNECT_RECV_COMM_BUS", + ]; + + for s in structs { + builder = builder.allowlist_type(s); + } + + // ==================== FUNCTIONS ==================== + let functions = [ + "SimConnect_MapClientEventToSimEvent", + "SimConnect_TransmitClientEvent", + "SimConnect_SetSystemEventState", + "SimConnect_AddClientEventToNotificationGroup", + "SimConnect_RemoveClientEvent", + "SimConnect_SetNotificationGroupPriority", + "SimConnect_ClearNotificationGroup", + "SimConnect_RequestNotificationGroup", + "SimConnect_AddToDataDefinition", + "SimConnect_ClearDataDefinition", + "SimConnect_RequestDataOnSimObject", + "SimConnect_RequestDataOnSimObjectType", + "SimConnect_SetDataOnSimObject", + "SimConnect_MapInputEventToClientEvent", + "SimConnect_SetInputGroupPriority", + "SimConnect_RemoveInputEvent", + "SimConnect_ClearInputGroup", + "SimConnect_SetInputGroupState", + "SimConnect_RequestReservedKey", + "SimConnect_SubscribeToSystemEvent", + "SimConnect_UnsubscribeFromSystemEvent", + "SimConnect_WeatherRequestInterpolatedObservation", + "SimConnect_WeatherRequestObservationAtStation", + "SimConnect_WeatherRequestObservationAtNearestStation", + "SimConnect_WeatherCreateStation", + "SimConnect_WeatherRemoveStation", + "SimConnect_WeatherSetObservation", + "SimConnect_WeatherSetModeServer", + "SimConnect_WeatherSetModeTheme", + "SimConnect_WeatherSetModeGlobal", + "SimConnect_WeatherSetModeCustom", + "SimConnect_WeatherSetDynamicUpdateRate", + "SimConnect_WeatherRequestCloudState", + "SimConnect_WeatherCreateThermal", + "SimConnect_WeatherRemoveThermal", + "SimConnect_AICreateParkedATCAircraft", + "SimConnect_AICreateEnrouteATCAircraft", + "SimConnect_AICreateNonATCAircraft", + "SimConnect_AICreateSimulatedObject", + "SimConnect_AIReleaseControl", + "SimConnect_AIRemoveObject", + "SimConnect_AISetAircraftFlightPlan", + "SimConnect_ExecuteMissionAction", + "SimConnect_CompleteCustomMissionAction", + "SimConnect_Close", + "SimConnect_RetrieveString", + "SimConnect_GetLastSentPacketID", + "SimConnect_Open", + "SimConnect_CallDispatch", + "SimConnect_GetNextDispatch", + "SimConnect_RequestResponseTimes", + "SimConnect_InsertString", + "SimConnect_CameraSetRelative6DOF", + "SimConnect_MenuAddItem", + "SimConnect_MenuDeleteItem", + "SimConnect_MenuAddSubItem", + "SimConnect_MenuDeleteSubItem", + "SimConnect_RequestSystemState", + "SimConnect_SetSystemState", + "SimConnect_MapClientDataNameToID", + "SimConnect_CreateClientData", + "SimConnect_AddToClientDataDefinition", + "SimConnect_ClearClientDataDefinition", + "SimConnect_RequestClientData", + "SimConnect_SetClientData", + "SimConnect_FlightLoad", + "SimConnect_FlightSave", + "SimConnect_FlightPlanLoad", + "SimConnect_Text", + "SimConnect_SubscribeToFacilities", + "SimConnect_UnsubscribeToFacilities", + "SimConnect_RequestFacilitiesList", + "SimConnect_TransmitClientEvent_EX1", + "SimConnect_AddToFacilityDefinition", + "SimConnect_RequestFacilityData", + "SimConnect_SubscribeToFacilities_EX1", + "SimConnect_UnsubscribeToFacilities_EX1", + "SimConnect_RequestFacilitiesList_EX1", + "SimConnect_RequestFacilityData_EX1", + "SimConnect_RequestJetwayData", + "SimConnect_EnumerateControllers", + "SimConnect_MapInputEventToClientEvent_EX1", + "SimConnect_ExecuteAction", + "SimConnect_EnumerateInputEvents", + "SimConnect_GetInputEvent", + "SimConnect_SetInputEvent", + "SimConnect_SubscribeInputEvent", + "SimConnect_UnsubscribeInputEvent", + "SimConnect_EnumerateInputEventParams", + "SimConnect_AddFacilityDataDefinitionFilter", + "SimConnect_ClearAllFacilityDataDefinitionFilters", + "SimConnect_AICreateParkedATCAircraft_EX1", + "SimConnect_AICreateEnrouteATCAircraft_EX1", + "SimConnect_AICreateNonATCAircraft_EX1", + "SimConnect_AICreateSimulatedObject_EX1", + "SimConnect_EnumerateSimObjectsAndLiveries", + "SimConnect_SubscribeToFlowEvent", + "SimConnect_UnsubscribeToFlowEvent", + "SimConnect_RequestAllFacilities", + "SimConnect_CameraAcquire", + "SimConnect_CameraRelease", + "SimConnect_CameraGetStatus", + "SimConnect_CameraSet", + "SimConnect_CameraGet", + "SimConnect_CameraEnableFlag", + "SimConnect_CameraDisableFlag", + "SimConnect_SubscribeToCameraStatusUpdate", + "SimConnect_UnsubscribeToCameraStatusUpdate", + "SimConnect_EnumerateCameraDefinitions", + "SimConnect_CameraSetUsingCameraDefinition", + "SimConnect_SubscribeToCommBusEvent", + "SimConnect_UnsubscribeToCommBusEvent", + "SimConnect_CallCommBusEvent", + "SimConnect_SubscribeToCameraWorldLockerStatusUpdate", + "SimConnect_UnsubscribeToCameraWorldLockerStatusUpdate", + "SimConnect_RequestCameraWorldLocker", + "SimConnect_DeleteCameraWorldLocker", + ]; + + for f in functions { + builder = builder.allowlist_function(f); + } + + let bindings = builder + .generate() + .expect("Unable to generate bindings"); + + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); + bindings + .write_to_file(out_path.join("bindings.rs")) + .expect("Couldn't write bindings!"); + }) + .expect("Failed to spawn bindgen thread"); + + handle.join().expect("Bindgen thread panicked"); +} diff --git a/simulators/FS2024/libsrc/include/SimConnect.hpp b/simulators/FS2024/libsrc/include/SimConnect.hpp new file mode 100644 index 0000000..1aeea8e --- /dev/null +++ b/simulators/FS2024/libsrc/include/SimConnect.hpp @@ -0,0 +1,1160 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All Rights Reserved. +// +//----------------------------------------------------------------------------- +// Updated per FS2024 SDK 1.6.9 + +#pragma once + +#include + +#ifndef _SIMCONNECT_H_ +#define _SIMCONNECT_H_ + +#ifdef _MSFS_WASM + #ifndef SIMCONNECT_WASM_MODULE + #define SIMCONNECT_WASM_MODULE "env" + #endif +#endif + +#ifndef DWORD_MAX +#define DWORD_MAX 0xFFFFFFFF +#endif + +#include + +typedef DWORD SIMCONNECT_OBJECT_ID; + +//---------------------------------------------------------------------------- +// Constants +//---------------------------------------------------------------------------- + +static const DWORD SIMCONNECT_UNUSED = DWORD_MAX; // special value to indicate unused event, ID +static const DWORD SIMCONNECT_OBJECT_ID_MAX = DWORD_MAX - 128; // proxy value for User vehicle ObjectID +static const DWORD SIMCONNECT_OBJECT_ID_USER = 0; // deprecated - proxy legacy value for User aircraft ObjectID +static const DWORD SIMCONNECT_OBJECT_ID_USER_AIRCRAFT = 0; // proxy value for User aircraft ObjectID +static const DWORD SIMCONNECT_OBJECT_ID_USER_AVATAR = SIMCONNECT_OBJECT_ID_MAX + 1; // proxy value for User avatar ObjectID +static const DWORD SIMCONNECT_OBJECT_ID_USER_CURRENT = SIMCONNECT_OBJECT_ID_MAX + 2; // proxy value for User aircraft/avatar ObjectID + +static const float SIMCONNECT_CAMERA_IGNORE_FIELD = FLT_MAX; //Used to tell the Camera API to NOT modify the value in this part of the argument. + +static const DWORD SIMCONNECT_CLIENTDATA_MAX_SIZE = 8192; // maximum value for SimConnect_CreateClientData dwSize parameter + + +// Notification Group priority values +static const DWORD SIMCONNECT_GROUP_PRIORITY_HIGHEST = 1; // highest priority +static const DWORD SIMCONNECT_GROUP_PRIORITY_HIGHEST_MASKABLE = 10000000; // highest priority that allows events to be masked +static const DWORD SIMCONNECT_GROUP_PRIORITY_STANDARD = 1900000000; // standard priority +static const DWORD SIMCONNECT_GROUP_PRIORITY_DEFAULT = 2000000000; // default priority +static const DWORD SIMCONNECT_GROUP_PRIORITY_LOWEST = 4000000000; // priorities lower than this will be ignored + +//Weather observations Metar strings +static const DWORD MAX_METAR_LENGTH = 2000; + +// Maximum thermal size is 100 km. +static const float MAX_THERMAL_SIZE = 100000; +static const float MAX_THERMAL_RATE = 1000; + +// SIMCONNECT_DATA_INITPOSITION.Airspeed +static const DWORD INITPOSITION_AIRSPEED_CRUISE = -1; // aircraft's cruise airspeed +static const DWORD INITPOSITION_AIRSPEED_KEEP = -2; // keep current airspeed + +// AddToClientDataDefinition dwSizeOrType parameter type values +static const DWORD SIMCONNECT_CLIENTDATATYPE_INT8 = -1; // 8-bit integer number +static const DWORD SIMCONNECT_CLIENTDATATYPE_INT16 = -2; // 16-bit integer number +static const DWORD SIMCONNECT_CLIENTDATATYPE_INT32 = -3; // 32-bit integer number +static const DWORD SIMCONNECT_CLIENTDATATYPE_INT64 = -4; // 64-bit integer number +static const DWORD SIMCONNECT_CLIENTDATATYPE_FLOAT32 = -5; // 32-bit floating-point number (float) +static const DWORD SIMCONNECT_CLIENTDATATYPE_FLOAT64 = -6; // 64-bit floating-point number (double) + +// AddToClientDataDefinition dwOffset parameter special values +static const DWORD SIMCONNECT_CLIENTDATAOFFSET_AUTO = -1; // automatically compute offset of the ClientData variable + +// Open ConfigIndex parameter special value +static const DWORD SIMCONNECT_OPEN_CONFIGINDEX_LOCAL = -1; // ignore SimConnect.cfg settings, and force local connection + +//---------------------------------------------------------------------------- +// Enum definitions +//---------------------------------------------------------------------------- + +//these came from substituteMacros +#define SIMCONNECT_REFSTRUCT struct +#define SIMCONNECT_STRUCT struct +#define SIMCONNECT_STRING(name, size) char name[size] +#define SIMCONNECT_GUID GUID +#define SIMCONNECT_STRINGV(name) char name[1] +#define SIMCONNECT_DATAV(name, id, count) DWORD name +#define SIMCONNECT_FIXEDTYPE_DATAV(type, name, count, cliMarshalAs, cliType) type name[1] +#define SIMCONNECT_GUID GUID +#define SIMCONNECT_ENUM enum +#define SIMCONNECT_ENUM_FLAGS typedef DWORD +#define SIMCONNECT_USER_ENUM typedef DWORD +#define SIMCONNECT_TYPEDEF(type, new_type) typedef type new_type; + +// Receive data types +SIMCONNECT_ENUM SIMCONNECT_RECV_ID +{ + SIMCONNECT_RECV_ID_NULL, + SIMCONNECT_RECV_ID_EXCEPTION, + SIMCONNECT_RECV_ID_OPEN, + SIMCONNECT_RECV_ID_QUIT, + SIMCONNECT_RECV_ID_EVENT, + SIMCONNECT_RECV_ID_EVENT_OBJECT_ADDREMOVE, + SIMCONNECT_RECV_ID_EVENT_FILENAME, + SIMCONNECT_RECV_ID_EVENT_FRAME, + SIMCONNECT_RECV_ID_SIMOBJECT_DATA, + SIMCONNECT_RECV_ID_SIMOBJECT_DATA_BYTYPE, + SIMCONNECT_RECV_ID_WEATHER_OBSERVATION, + SIMCONNECT_RECV_ID_CLOUD_STATE, + SIMCONNECT_RECV_ID_ASSIGNED_OBJECT_ID, + SIMCONNECT_RECV_ID_RESERVED_KEY, + SIMCONNECT_RECV_ID_CUSTOM_ACTION, + SIMCONNECT_RECV_ID_SYSTEM_STATE, + SIMCONNECT_RECV_ID_CLIENT_DATA, + SIMCONNECT_RECV_ID_EVENT_WEATHER_MODE, + SIMCONNECT_RECV_ID_AIRPORT_LIST, + SIMCONNECT_RECV_ID_VOR_LIST, + SIMCONNECT_RECV_ID_NDB_LIST, + SIMCONNECT_RECV_ID_WAYPOINT_LIST, + SIMCONNECT_RECV_ID_EVENT_MULTIPLAYER_SERVER_STARTED, + SIMCONNECT_RECV_ID_EVENT_MULTIPLAYER_CLIENT_STARTED, + SIMCONNECT_RECV_ID_EVENT_MULTIPLAYER_SESSION_ENDED, + SIMCONNECT_RECV_ID_EVENT_RACE_END, + SIMCONNECT_RECV_ID_EVENT_RACE_LAP, + SIMCONNECT_RECV_ID_EVENT_EX1, + SIMCONNECT_RECV_ID_FACILITY_DATA, + SIMCONNECT_RECV_ID_FACILITY_DATA_END, + SIMCONNECT_RECV_ID_FACILITY_MINIMAL_LIST, + SIMCONNECT_RECV_ID_JETWAY_DATA, + SIMCONNECT_RECV_ID_CONTROLLERS_LIST, + SIMCONNECT_RECV_ID_ACTION_CALLBACK, + SIMCONNECT_RECV_ID_ENUMERATE_INPUT_EVENTS, + SIMCONNECT_RECV_ID_GET_INPUT_EVENT, + SIMCONNECT_RECV_ID_SUBSCRIBE_INPUT_EVENT, + SIMCONNECT_RECV_ID_ENUMERATE_INPUT_EVENT_PARAMS, + SIMCONNECT_RECV_ID_ENUMERATE_SIMOBJECT_AND_LIVERY_LIST, + SIMCONNECT_RECV_ID_FLOW_EVENT, + SIMCONNECT_RECV_ID_CAMERA_DATA, + SIMCONNECT_RECV_ID_CAMERA_STATUS, + SIMCONNECT_RECV_ID_CAMERA_DEFINITION_LIST, + SIMCONNECT_RECV_ID_COMM_BUS, + SIMCONNECT_RECV_ID_CAMERA_WORLD_LOCKER, +}; + +// Data data types +SIMCONNECT_ENUM SIMCONNECT_DATATYPE:int +{ + SIMCONNECT_DATATYPE_INVALID, // invalid data type + SIMCONNECT_DATATYPE_INT32, // 32-bit integer number + SIMCONNECT_DATATYPE_INT64, // 64-bit integer number + SIMCONNECT_DATATYPE_FLOAT32, // 32-bit floating-point number (float) + SIMCONNECT_DATATYPE_FLOAT64, // 64-bit floating-point number (double) + SIMCONNECT_DATATYPE_STRING8, // 8-byte string + SIMCONNECT_DATATYPE_STRING32, // 32-byte string + SIMCONNECT_DATATYPE_STRING64, // 64-byte string + SIMCONNECT_DATATYPE_STRING128, // 128-byte string + SIMCONNECT_DATATYPE_STRING256, // 256-byte string + SIMCONNECT_DATATYPE_STRING260, // 260-byte string + SIMCONNECT_DATATYPE_STRINGV, // variable-length string + SIMCONNECT_DATATYPE_INITPOSITION, // see SIMCONNECT_DATA_INITPOSITION + SIMCONNECT_DATATYPE_MARKERSTATE, // see SIMCONNECT_DATA_MARKERSTATE + SIMCONNECT_DATATYPE_WAYPOINT, // see SIMCONNECT_DATA_WAYPOINT + SIMCONNECT_DATATYPE_LATLONALT, // see SIMCONNECT_DATA_LATLONALT + SIMCONNECT_DATATYPE_XYZ, // see SIMCONNECT_DATA_XYZ + SIMCONNECT_DATATYPE_INT8, // 8-bit integer number, char + + SIMCONNECT_DATATYPE_MAX // enum limit +}; + +// Exception error types +SIMCONNECT_ENUM SIMCONNECT_EXCEPTION +{ + SIMCONNECT_EXCEPTION_NONE, + + SIMCONNECT_EXCEPTION_ERROR, + SIMCONNECT_EXCEPTION_SIZE_MISMATCH, + SIMCONNECT_EXCEPTION_UNRECOGNIZED_ID, + SIMCONNECT_EXCEPTION_UNOPENED, + SIMCONNECT_EXCEPTION_VERSION_MISMATCH, + SIMCONNECT_EXCEPTION_TOO_MANY_GROUPS, + SIMCONNECT_EXCEPTION_NAME_UNRECOGNIZED, + SIMCONNECT_EXCEPTION_TOO_MANY_EVENT_NAMES, + SIMCONNECT_EXCEPTION_EVENT_ID_DUPLICATE, + SIMCONNECT_EXCEPTION_TOO_MANY_MAPS, + SIMCONNECT_EXCEPTION_TOO_MANY_OBJECTS, + SIMCONNECT_EXCEPTION_TOO_MANY_REQUESTS, + SIMCONNECT_EXCEPTION_WEATHER_INVALID_PORT, + SIMCONNECT_EXCEPTION_WEATHER_INVALID_METAR, + SIMCONNECT_EXCEPTION_WEATHER_UNABLE_TO_GET_OBSERVATION, + SIMCONNECT_EXCEPTION_WEATHER_UNABLE_TO_CREATE_STATION, + SIMCONNECT_EXCEPTION_WEATHER_UNABLE_TO_REMOVE_STATION, + SIMCONNECT_EXCEPTION_INVALID_DATA_TYPE, + SIMCONNECT_EXCEPTION_INVALID_DATA_SIZE, + SIMCONNECT_EXCEPTION_DATA_ERROR, + SIMCONNECT_EXCEPTION_INVALID_ARRAY, + SIMCONNECT_EXCEPTION_CREATE_OBJECT_FAILED, + SIMCONNECT_EXCEPTION_LOAD_FLIGHTPLAN_FAILED, + SIMCONNECT_EXCEPTION_OPERATION_INVALID_FOR_OBJECT_TYPE, + SIMCONNECT_EXCEPTION_ILLEGAL_OPERATION, + SIMCONNECT_EXCEPTION_ALREADY_SUBSCRIBED, + SIMCONNECT_EXCEPTION_INVALID_ENUM, + SIMCONNECT_EXCEPTION_DEFINITION_ERROR, + SIMCONNECT_EXCEPTION_DUPLICATE_ID, + SIMCONNECT_EXCEPTION_DATUM_ID, + SIMCONNECT_EXCEPTION_OUT_OF_BOUNDS, + SIMCONNECT_EXCEPTION_ALREADY_CREATED, + SIMCONNECT_EXCEPTION_OBJECT_OUTSIDE_REALITY_BUBBLE, + SIMCONNECT_EXCEPTION_OBJECT_CONTAINER, + SIMCONNECT_EXCEPTION_OBJECT_AI, + SIMCONNECT_EXCEPTION_OBJECT_ATC, + SIMCONNECT_EXCEPTION_OBJECT_SCHEDULE, + SIMCONNECT_EXCEPTION_JETWAY_DATA, + SIMCONNECT_EXCEPTION_ACTION_NOT_FOUND, + SIMCONNECT_EXCEPTION_NOT_AN_ACTION, + SIMCONNECT_EXCEPTION_INCORRECT_ACTION_PARAMS, + SIMCONNECT_EXCEPTION_GET_INPUT_EVENT_FAILED, + SIMCONNECT_EXCEPTION_SET_INPUT_EVENT_FAILED, + SIMCONNECT_EXCEPTION_EVENT_NAME_RESERVED, + SIMCONNECT_EXCEPTION_INTERNAL, + SIMCONNECT_EXCEPTION_CAMERA_API, +}; + +// Object types +SIMCONNECT_ENUM SIMCONNECT_SIMOBJECT_TYPE +{ + SIMCONNECT_SIMOBJECT_TYPE_USER = 0, + SIMCONNECT_SIMOBJECT_TYPE_USER_AIRCRAFT = 0, + SIMCONNECT_SIMOBJECT_TYPE_ALL, + SIMCONNECT_SIMOBJECT_TYPE_AIRCRAFT, + SIMCONNECT_SIMOBJECT_TYPE_HELICOPTER, + SIMCONNECT_SIMOBJECT_TYPE_BOAT, + SIMCONNECT_SIMOBJECT_TYPE_GROUND, + SIMCONNECT_SIMOBJECT_TYPE_HOT_AIR_BALLOON, + SIMCONNECT_SIMOBJECT_TYPE_ANIMAL, + SIMCONNECT_SIMOBJECT_TYPE_USER_AVATAR, + SIMCONNECT_SIMOBJECT_TYPE_USER_CURRENT, +}; + +// EventState values +SIMCONNECT_ENUM SIMCONNECT_STATE +{ + SIMCONNECT_STATE_OFF, + SIMCONNECT_STATE_ON, +}; + +// Object Data Request Period values +SIMCONNECT_ENUM SIMCONNECT_PERIOD +{ + SIMCONNECT_PERIOD_NEVER, + SIMCONNECT_PERIOD_ONCE, + SIMCONNECT_PERIOD_VISUAL_FRAME, + SIMCONNECT_PERIOD_SIM_FRAME, + SIMCONNECT_PERIOD_SECOND, +}; + +SIMCONNECT_ENUM SIMCONNECT_MISSION_END +{ + SIMCONNECT_MISSION_FAILED, + SIMCONNECT_MISSION_CRASHED, + SIMCONNECT_MISSION_SUCCEEDED +}; + +// ClientData Request Period values +SIMCONNECT_ENUM SIMCONNECT_CLIENT_DATA_PERIOD +{ + SIMCONNECT_CLIENT_DATA_PERIOD_NEVER, + SIMCONNECT_CLIENT_DATA_PERIOD_ONCE, + SIMCONNECT_CLIENT_DATA_PERIOD_VISUAL_FRAME, + SIMCONNECT_CLIENT_DATA_PERIOD_ON_SET, + SIMCONNECT_CLIENT_DATA_PERIOD_SECOND, +}; + +SIMCONNECT_ENUM SIMCONNECT_TEXT_TYPE +{ + SIMCONNECT_TEXT_TYPE_SCROLL_BLACK, + SIMCONNECT_TEXT_TYPE_SCROLL_WHITE, + SIMCONNECT_TEXT_TYPE_SCROLL_RED, + SIMCONNECT_TEXT_TYPE_SCROLL_GREEN, + SIMCONNECT_TEXT_TYPE_SCROLL_BLUE, + SIMCONNECT_TEXT_TYPE_SCROLL_YELLOW, + SIMCONNECT_TEXT_TYPE_SCROLL_MAGENTA, + SIMCONNECT_TEXT_TYPE_SCROLL_CYAN, + SIMCONNECT_TEXT_TYPE_PRINT_BLACK = 0x0100, + SIMCONNECT_TEXT_TYPE_PRINT_WHITE, + SIMCONNECT_TEXT_TYPE_PRINT_RED, + SIMCONNECT_TEXT_TYPE_PRINT_GREEN, + SIMCONNECT_TEXT_TYPE_PRINT_BLUE, + SIMCONNECT_TEXT_TYPE_PRINT_YELLOW, + SIMCONNECT_TEXT_TYPE_PRINT_MAGENTA, + SIMCONNECT_TEXT_TYPE_PRINT_CYAN, + SIMCONNECT_TEXT_TYPE_MENU = 0x0200, +}; + +SIMCONNECT_ENUM SIMCONNECT_TEXT_RESULT +{ + SIMCONNECT_TEXT_RESULT_MENU_SELECT_1, + SIMCONNECT_TEXT_RESULT_MENU_SELECT_2, + SIMCONNECT_TEXT_RESULT_MENU_SELECT_3, + SIMCONNECT_TEXT_RESULT_MENU_SELECT_4, + SIMCONNECT_TEXT_RESULT_MENU_SELECT_5, + SIMCONNECT_TEXT_RESULT_MENU_SELECT_6, + SIMCONNECT_TEXT_RESULT_MENU_SELECT_7, + SIMCONNECT_TEXT_RESULT_MENU_SELECT_8, + SIMCONNECT_TEXT_RESULT_MENU_SELECT_9, + SIMCONNECT_TEXT_RESULT_MENU_SELECT_10, + SIMCONNECT_TEXT_RESULT_DISPLAYED = 0x00010000, + SIMCONNECT_TEXT_RESULT_QUEUED, + SIMCONNECT_TEXT_RESULT_REMOVED, + SIMCONNECT_TEXT_RESULT_REPLACED, + SIMCONNECT_TEXT_RESULT_TIMEOUT, +}; + +SIMCONNECT_ENUM SIMCONNECT_WEATHER_MODE +{ + SIMCONNECT_WEATHER_MODE_THEME, + SIMCONNECT_WEATHER_MODE_RWW, + SIMCONNECT_WEATHER_MODE_CUSTOM, + SIMCONNECT_WEATHER_MODE_GLOBAL, +}; + +SIMCONNECT_ENUM SIMCONNECT_FACILITY_LIST_TYPE +{ + SIMCONNECT_FACILITY_LIST_TYPE_AIRPORT, + SIMCONNECT_FACILITY_LIST_TYPE_WAYPOINT, + SIMCONNECT_FACILITY_LIST_TYPE_NDB, + SIMCONNECT_FACILITY_LIST_TYPE_VOR, + SIMCONNECT_FACILITY_LIST_TYPE_COUNT // invalid +}; + +SIMCONNECT_ENUM SIMCONNECT_FACILITY_DATA_TYPE +{ + SIMCONNECT_FACILITY_DATA_AIRPORT, + SIMCONNECT_FACILITY_DATA_RUNWAY, + SIMCONNECT_FACILITY_DATA_START, + SIMCONNECT_FACILITY_DATA_FREQUENCY, + SIMCONNECT_FACILITY_DATA_HELIPAD, + SIMCONNECT_FACILITY_DATA_APPROACH, + SIMCONNECT_FACILITY_DATA_APPROACH_TRANSITION, + SIMCONNECT_FACILITY_DATA_APPROACH_LEG, + SIMCONNECT_FACILITY_DATA_FINAL_APPROACH_LEG, + SIMCONNECT_FACILITY_DATA_MISSED_APPROACH_LEG, + SIMCONNECT_FACILITY_DATA_DEPARTURE, + SIMCONNECT_FACILITY_DATA_ARRIVAL, + SIMCONNECT_FACILITY_DATA_RUNWAY_TRANSITION, + SIMCONNECT_FACILITY_DATA_ENROUTE_TRANSITION, + SIMCONNECT_FACILITY_DATA_TAXI_POINT, + SIMCONNECT_FACILITY_DATA_TAXI_PARKING, + SIMCONNECT_FACILITY_DATA_TAXI_PATH, + SIMCONNECT_FACILITY_DATA_TAXI_NAME, + SIMCONNECT_FACILITY_DATA_JETWAY, + SIMCONNECT_FACILITY_DATA_VOR, + SIMCONNECT_FACILITY_DATA_NDB, + SIMCONNECT_FACILITY_DATA_WAYPOINT, + SIMCONNECT_FACILITY_DATA_ROUTE, + SIMCONNECT_FACILITY_DATA_PAVEMENT, + SIMCONNECT_FACILITY_DATA_APPROACH_LIGHTS, + SIMCONNECT_FACILITY_DATA_VASI, + SIMCONNECT_FACILITY_DATA_VDGS, + SIMCONNECT_FACILITY_DATA_HOLDING_PATTERN, + SIMCONNECT_FACILITY_DATA_TAXI_PARKING_AIRLINE, +}; + +SIMCONNECT_ENUM SIMCONNECT_INPUT_EVENT_TYPE : DWORD +{ + SIMCONNECT_INPUT_EVENT_TYPE_DOUBLE, + SIMCONNECT_INPUT_EVENT_TYPE_STRING +}; + +SIMCONNECT_ENUM SIMCONNECT_FLOW_EVENT : DWORD +{ + SIMCONNECT_FLOW_EVENT_NONE, + SIMCONNECT_FLOW_EVENT_FLT_LOAD, + SIMCONNECT_FLOW_EVENT_FLT_LOADED, + SIMCONNECT_FLOW_EVENT_TELEPORT_START, + SIMCONNECT_FLOW_EVENT_TELEPORT_DONE, + SIMCONNECT_FLOW_EVENT_BACK_ON_TRACK_START, + SIMCONNECT_FLOW_EVENT_BACK_ON_TRACK_DONE, + SIMCONNECT_FLOW_EVENT_SKIP_START, + SIMCONNECT_FLOW_EVENT_SKIP_DONE, + SIMCONNECT_FLOW_EVENT_BACK_TO_MAIN_MENU, + SIMCONNECT_FLOW_EVENT_RTC_START, + SIMCONNECT_FLOW_EVENT_RTC_END, + SIMCONNECT_FLOW_EVENT_REPLAY_START, + SIMCONNECT_FLOW_EVENT_REPLAY_END, + SIMCONNECT_FLOW_EVENT_FLIGHT_START, + SIMCONNECT_FLOW_EVENT_FLIGHT_END, + SIMCONNECT_FLOW_EVENT_PLANE_CRASH, +}; + + +SIMCONNECT_ENUM_FLAGS SIMCONNECT_VOR_FLAGS; // flags for SIMCONNECT_RECV_ID_VOR_LIST + static const DWORD SIMCONNECT_RECV_ID_VOR_LIST_HAS_NAV_SIGNAL = 0x00000001; // Has Nav signal + static const DWORD SIMCONNECT_RECV_ID_VOR_LIST_HAS_LOCALIZER = 0x00000002; // Has localizer + static const DWORD SIMCONNECT_RECV_ID_VOR_LIST_HAS_GLIDE_SLOPE = 0x00000004; // Has Nav signal + static const DWORD SIMCONNECT_RECV_ID_VOR_LIST_HAS_DME = 0x00000008; // Station has DME + +// bits for the Waypoint Flags field: may be combined +SIMCONNECT_ENUM_FLAGS SIMCONNECT_WAYPOINT_FLAGS; + static const DWORD SIMCONNECT_WAYPOINT_NONE = 0x00; + static const DWORD SIMCONNECT_WAYPOINT_SPEED_REQUESTED = 0x04; // requested speed at waypoint is valid + static const DWORD SIMCONNECT_WAYPOINT_THROTTLE_REQUESTED = 0x08; // request a specific throttle percentage + static const DWORD SIMCONNECT_WAYPOINT_COMPUTE_VERTICAL_SPEED = 0x10; // compute vertical to speed to reach waypoint altitude when crossing the waypoint + static const DWORD SIMCONNECT_WAYPOINT_ALTITUDE_IS_AGL = 0x20; // AltitudeIsAGL + static const DWORD SIMCONNECT_WAYPOINT_ON_GROUND = 0x00100000; // place this waypoint on the ground + static const DWORD SIMCONNECT_WAYPOINT_REVERSE = 0x00200000; // Back up to this waypoint. Only valid on first waypoint + static const DWORD SIMCONNECT_WAYPOINT_WRAP_TO_FIRST = 0x00400000; // Wrap around back to first waypoint. Only valid on last waypoint. + static const DWORD SIMCONNECT_WAYPOINT_ALWAYS_BACKUP = 0x00800000; // Go from first waypoint to last one moving only backwards + static const DWORD SIMCONNECT_WAYPOINT_KEEP_LAST_HEADING = 0x01000000; // Object doesn't only go from waypoint to waypoint using position but it will also keep the same heading computed on the last 2 waypoints + static const DWORD SIMCONNECT_WAYPOINT_YIELD_TO_USER = 0x02000000; // Object will never be too close of the player. If waypoints pass too close of the player, the object will stop and wait + static const DWORD SIMCONNECT_WAYPOINT_CAN_REVERSE = 0x04000000; // This flags handle the behaviour of the object if it can't reach a waypoint. By default, it will take a other way and try to reach this point again. With this flag, object will try some stuff to reach this waypoint in a better condition (moving backwards...) + +SIMCONNECT_ENUM_FLAGS SIMCONNECT_EVENT_FLAG; + static const DWORD SIMCONNECT_EVENT_FLAG_DEFAULT = 0x00000000; + static const DWORD SIMCONNECT_EVENT_FLAG_FAST_REPEAT_TIMER = 0x00000001; // set event repeat timer to simulate fast repeat + static const DWORD SIMCONNECT_EVENT_FLAG_SLOW_REPEAT_TIMER = 0x00000002; // set event repeat timer to simulate slow repeat + static const DWORD SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY = 0x00000010; // interpret GroupID parameter as priority value + +SIMCONNECT_ENUM_FLAGS SIMCONNECT_DATA_REQUEST_FLAG; + static const DWORD SIMCONNECT_DATA_REQUEST_FLAG_DEFAULT = 0x00000000; + static const DWORD SIMCONNECT_DATA_REQUEST_FLAG_CHANGED = 0x00000001; // send requested data when value(s) change + static const DWORD SIMCONNECT_DATA_REQUEST_FLAG_TAGGED = 0x00000002; // send requested data in tagged format + +SIMCONNECT_ENUM_FLAGS SIMCONNECT_DATA_SET_FLAG; + static const DWORD SIMCONNECT_DATA_SET_FLAG_DEFAULT = 0x00000000; + static const DWORD SIMCONNECT_DATA_SET_FLAG_TAGGED = 0x00000001; // data is in tagged format + +SIMCONNECT_ENUM_FLAGS SIMCONNECT_CREATE_CLIENT_DATA_FLAG; + static const DWORD SIMCONNECT_CREATE_CLIENT_DATA_FLAG_DEFAULT = 0x00000000; + static const DWORD SIMCONNECT_CREATE_CLIENT_DATA_FLAG_READ_ONLY = 0x00000001; // permit only ClientData creator to write into ClientData + +SIMCONNECT_ENUM_FLAGS SIMCONNECT_CLIENT_DATA_REQUEST_FLAG; + static const DWORD SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_DEFAULT = 0x00000000; + static const DWORD SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_CHANGED = 0x00000001; // send requested ClientData when value(s) change + static const DWORD SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_TAGGED = 0x00000002; // send requested ClientData in tagged format + +SIMCONNECT_ENUM_FLAGS SIMCONNECT_CLIENT_DATA_SET_FLAG; + static const DWORD SIMCONNECT_CLIENT_DATA_SET_FLAG_DEFAULT = 0x00000000; + static const DWORD SIMCONNECT_CLIENT_DATA_SET_FLAG_TAGGED = 0x00000001; // data is in tagged format + +SIMCONNECT_ENUM_FLAGS SIMCONNECT_VIEW_SYSTEM_EVENT_DATA; // dwData contains these flags for the "View" System Event + static const DWORD SIMCONNECT_VIEW_SYSTEM_EVENT_DATA_COCKPIT_2D = 0x00000001; // 2D Panels in cockpit view + static const DWORD SIMCONNECT_VIEW_SYSTEM_EVENT_DATA_COCKPIT_VIRTUAL = 0x00000002; // Virtual (3D) panels in cockpit view + static const DWORD SIMCONNECT_VIEW_SYSTEM_EVENT_DATA_ORTHOGONAL = 0x00000004; // Orthogonal (Map) view + +SIMCONNECT_ENUM_FLAGS SIMCONNECT_SOUND_SYSTEM_EVENT_DATA; // dwData contains these flags for the "Sound" System Event + static const DWORD SIMCONNECT_SOUND_SYSTEM_EVENT_DATA_MASTER = 0x00000001; // Sound Master + +SIMCONNECT_ENUM_FLAGS SIMCONNECT_COMM_BUS_BROADCAST_TO; + static const DWORD SIMCONNECT_COMM_BUS_BROADCAST_TO_JS = 1 << 0; + static const DWORD SIMCONNECT_COMM_BUS_BROADCAST_TO_WASM = 1 << 1; + static const DWORD SIMCONNECT_COMM_BUS_BROADCAST_TO_SIMCONNECT = 1 << 3; + static const DWORD SIMCONNECT_COMM_BUS_BROADCAST_TO_SIMCONNECT_SELF_CALL = 1 << 4; // need SIMCONNECT_COMM_BUS_BROADCAST_TO_SIMCONNECT, allow the client to broadcast to itself + static const DWORD SIMCONNECT_COMM_BUS_BROADCAST_TO_DEFAULT = SIMCONNECT_COMM_BUS_BROADCAST_TO_JS | SIMCONNECT_COMM_BUS_BROADCAST_TO_WASM | SIMCONNECT_COMM_BUS_BROADCAST_TO_SIMCONNECT; + static const DWORD SIMCONNECT_COMM_BUS_BROADCAST_TO_ALL_SIMCONNECT = SIMCONNECT_COMM_BUS_BROADCAST_TO_SIMCONNECT | SIMCONNECT_COMM_BUS_BROADCAST_TO_SIMCONNECT_SELF_CALL; + static const DWORD SIMCONNECT_COMM_BUS_BROADCAST_TO_ALL = SIMCONNECT_COMM_BUS_BROADCAST_TO_JS | SIMCONNECT_COMM_BUS_BROADCAST_TO_WASM | SIMCONNECT_COMM_BUS_BROADCAST_TO_SIMCONNECT | SIMCONNECT_COMM_BUS_BROADCAST_TO_SIMCONNECT_SELF_CALL; + + + +//---------------------------------------------------------------------------- +// User-defined enums +//---------------------------------------------------------------------------- + +SIMCONNECT_USER_ENUM SIMCONNECT_NOTIFICATION_GROUP_ID; //client-defined notification group ID +SIMCONNECT_USER_ENUM SIMCONNECT_INPUT_GROUP_ID; //client-defined input group ID +SIMCONNECT_USER_ENUM SIMCONNECT_DATA_DEFINITION_ID; //client-defined data definition ID +SIMCONNECT_USER_ENUM SIMCONNECT_DATA_REQUEST_ID; //client-defined request data ID + +SIMCONNECT_USER_ENUM SIMCONNECT_CLIENT_EVENT_ID; //client-defined client event ID +SIMCONNECT_USER_ENUM SIMCONNECT_CLIENT_DATA_ID; //client-defined client data ID +SIMCONNECT_USER_ENUM SIMCONNECT_CLIENT_DATA_DEFINITION_ID; //client-defined client data definition ID + + +//---------------------------------------------------------------------------- +// Struct definitions +//---------------------------------------------------------------------------- + +#pragma pack(push, 1) + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV +{ + DWORD dwSize; // record size + DWORD dwVersion; // interface version + DWORD dwID; // see SIMCONNECT_RECV_ID +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_EXCEPTION : public SIMCONNECT_RECV // when dwID == SIMCONNECT_RECV_ID_EXCEPTION +{ + DWORD dwException; // see SIMCONNECT_EXCEPTION + static const DWORD UNKNOWN_SENDID = 0; + DWORD dwSendID; // see SimConnect_GetLastSentPacketID + static const DWORD UNKNOWN_INDEX = DWORD_MAX; + DWORD dwIndex; // index of parameter that was source of error +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_OPEN : public SIMCONNECT_RECV // when dwID == SIMCONNECT_RECV_ID_OPEN +{ + SIMCONNECT_STRING( szApplicationName, 256); + DWORD dwApplicationVersionMajor; + DWORD dwApplicationVersionMinor; + DWORD dwApplicationBuildMajor; + DWORD dwApplicationBuildMinor; + DWORD dwSimConnectVersionMajor; + DWORD dwSimConnectVersionMinor; + DWORD dwSimConnectBuildMajor; + DWORD dwSimConnectBuildMinor; + DWORD dwReserved1; + DWORD dwReserved2; +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_QUIT : public SIMCONNECT_RECV // when dwID == SIMCONNECT_RECV_ID_QUIT +{}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_EVENT : public SIMCONNECT_RECV // when dwID == SIMCONNECT_RECV_ID_EVENT +{ + static const DWORD UNKNOWN_GROUP = DWORD_MAX; + DWORD uGroupID; + DWORD uEventID; + DWORD dwData; // uEventID-dependent context +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_EVENT_FILENAME : public SIMCONNECT_RECV_EVENT // when dwID == SIMCONNECT_RECV_ID_EVENT_FILENAME +{ + SIMCONNECT_STRING( szFileName, MAX_PATH); // uEventID-dependent context + DWORD dwFlags; +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_EVENT_OBJECT_ADDREMOVE : public SIMCONNECT_RECV_EVENT // when dwID == SIMCONNECT_RECV_ID_EVENT_FILENAME +{ + SIMCONNECT_SIMOBJECT_TYPE eObjType; +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_EVENT_FRAME : public SIMCONNECT_RECV_EVENT // when dwID == SIMCONNECT_RECV_ID_EVENT_FRAME +{ + float fFrameRate; + float fSimSpeed; +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_EVENT_MULTIPLAYER_SERVER_STARTED : public SIMCONNECT_RECV_EVENT // when dwID == SIMCONNECT_RECV_ID_EVENT_MULTIPLAYER_SERVER_STARTED +{ + // No event specific data, for now +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_EVENT_MULTIPLAYER_CLIENT_STARTED : public SIMCONNECT_RECV_EVENT // when dwID == SIMCONNECT_RECV_ID_EVENT_MULTIPLAYER_CLIENT_STARTED +{ + // No event specific data, for now +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_EVENT_MULTIPLAYER_SESSION_ENDED : public SIMCONNECT_RECV_EVENT // when dwID == SIMCONNECT_RECV_ID_EVENT_MULTIPLAYER_SESSION_ENDED +{ + // No event specific data, for now +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_EVENT_EX1 : public SIMCONNECT_RECV // when dwID == SIMCONNECT_RECV_ID_EVENT_EX1 +{ + static const DWORD UNKNOWN_GROUP = DWORD_MAX; + DWORD uGroupID; + DWORD uEventID; + + // Doesn t support array so, let s list + DWORD dwData0; + DWORD dwData1; + DWORD dwData2; + DWORD dwData3; + DWORD dwData4; +}; + +// SIMCONNECT_DATA_RACE_RESULT +SIMCONNECT_STRUCT SIMCONNECT_DATA_RACE_RESULT +{ + DWORD dwNumberOfRacers; // The total number of racers + SIMCONNECT_GUID MissionGUID; // The name of the mission to execute, NULL if no mission + SIMCONNECT_STRING( szPlayerName, MAX_PATH); // The name of the player + SIMCONNECT_STRING( szSessionType, MAX_PATH); // The type of the multiplayer session: "LAN", "GAMESPY") + SIMCONNECT_STRING( szAircraft, MAX_PATH); // The aircraft type + SIMCONNECT_STRING( szPlayerRole, MAX_PATH); // The player role in the mission + double fTotalTime; // Total time in seconds, 0 means DNF + double fPenaltyTime; // Total penalty time in seconds + DWORD dwIsDisqualified; // non 0 - disqualified, 0 - not disqualified +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_EVENT_RACE_END : public SIMCONNECT_RECV_EVENT // when dwID == SIMCONNECT_RECV_ID_EVENT_RACE_END +{ + DWORD dwRacerNumber; // The index of the racer the results are for + SIMCONNECT_DATA_RACE_RESULT RacerData; +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_EVENT_RACE_LAP : public SIMCONNECT_RECV_EVENT // when dwID == SIMCONNECT_RECV_ID_EVENT_RACE_LAP +{ + DWORD dwLapIndex; // The index of the lap the results are for + SIMCONNECT_DATA_RACE_RESULT RacerData; +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_SIMOBJECT_DATA : public SIMCONNECT_RECV // when dwID == SIMCONNECT_RECV_ID_SIMOBJECT_DATA +{ + DWORD dwRequestID; + DWORD dwObjectID; + DWORD dwDefineID; + DWORD dwFlags; // SIMCONNECT_DATA_REQUEST_FLAG + DWORD dwentrynumber; // if multiple objects returned, this is number out of . + DWORD dwoutof; // note: starts with 1, not 0. + DWORD dwDefineCount; // data count (number of datums, *not* byte count) + SIMCONNECT_DATAV( dwData, dwDefineID, ); // data begins here, dwDefineCount data items +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_SIMOBJECT_DATA_BYTYPE : public SIMCONNECT_RECV_SIMOBJECT_DATA // when dwID == SIMCONNECT_RECV_ID_SIMOBJECT_DATA_BYTYPE +{ +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_CLIENT_DATA : public SIMCONNECT_RECV_SIMOBJECT_DATA // when dwID == SIMCONNECT_RECV_ID_CLIENT_DATA +{ +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_WEATHER_OBSERVATION : public SIMCONNECT_RECV // when dwID == SIMCONNECT_RECV_ID_WEATHER_OBSERVATION +{ + DWORD dwRequestID; + SIMCONNECT_STRINGV( szMetar); // Variable length string whose maximum size is MAX_METAR_LENGTH +}; + +static const int SIMCONNECT_CLOUD_STATE_ARRAY_WIDTH = 64; +static const int SIMCONNECT_CLOUD_STATE_ARRAY_SIZE = SIMCONNECT_CLOUD_STATE_ARRAY_WIDTH*SIMCONNECT_CLOUD_STATE_ARRAY_WIDTH; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_CLOUD_STATE : public SIMCONNECT_RECV // when dwID == SIMCONNECT_RECV_ID_CLOUD_STATE +{ + DWORD dwRequestID; + DWORD dwArraySize; + SIMCONNECT_FIXEDTYPE_DATAV(BYTE, rgbData, dwArraySize, U1 /*member of UnmanagedType enum*/ , System::Byte /*cli type*/); +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_ASSIGNED_OBJECT_ID : public SIMCONNECT_RECV // when dwID == SIMCONNECT_RECV_ID_ASSIGNED_OBJECT_ID +{ + DWORD dwRequestID; + DWORD dwObjectID; +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_RESERVED_KEY : public SIMCONNECT_RECV // when dwID == SIMCONNECT_RECV_ID_RESERVED_KEY +{ + SIMCONNECT_STRING( szChoiceReserved, 30); + SIMCONNECT_STRING( szReservedKey, 50); +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_SYSTEM_STATE : public SIMCONNECT_RECV // when dwID == SIMCONNECT_RECV_ID_SYSTEM_STATE +{ + DWORD dwRequestID; + DWORD dwInteger; + float fFloat; + SIMCONNECT_STRING( szString, MAX_PATH); +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_CUSTOM_ACTION : public SIMCONNECT_RECV_EVENT +{ + SIMCONNECT_GUID guidInstanceId; // Instance id of the action that executed + DWORD dwWaitForCompletion; // Wait for completion flag on the action + SIMCONNECT_STRINGV( szPayLoad); // Variable length string payload associated with the mission action. +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_EVENT_WEATHER_MODE : public SIMCONNECT_RECV_EVENT +{ + // No event specific data - the new weather mode is in the base structure dwData member. +}; + +// SIMCONNECT_RECV_FACILITIES_LIST +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_FACILITIES_LIST : public SIMCONNECT_RECV +{ + DWORD dwRequestID; + DWORD dwArraySize; + DWORD dwEntryNumber; // when the array of items is too big for one send, which send this is (0..dwOutOf-1) + DWORD dwOutOf; // total number of transmissions the list is chopped into +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_LIST_TEMPLATE : public SIMCONNECT_RECV +{ + DWORD dwRequestID; + DWORD dwArraySize; + DWORD dwEntryNumber; // when the array of items is too big for one send, which send this is (0..dwOutOf-1) + DWORD dwOutOf; // total number of transmissions the list is chopped into +}; + +// SIMCONNECT_DATA_FACILITY_AIRPORT +SIMCONNECT_REFSTRUCT SIMCONNECT_DATA_FACILITY_AIRPORT +{ + SIMCONNECT_STRING(Ident, 9); // ICAO of the object + SIMCONNECT_STRING(Region, 3); // ICAO of the object + double Latitude; // degrees + double Longitude; // degrees + double Altitude; // meters +}; + +// SIMCONNECT_RECV_AIRPORT_LIST +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_AIRPORT_LIST : public SIMCONNECT_RECV_FACILITIES_LIST +{ + SIMCONNECT_FIXEDTYPE_DATAV(SIMCONNECT_DATA_FACILITY_AIRPORT, rgData, dwArraySize, U1 /*member of UnmanagedType enum*/, SIMCONNECT_DATA_FACILITY_AIRPORT /*cli type*/); +}; + +// SIMCONNECT_DATA_FACILITY_WAYPOINT +SIMCONNECT_REFSTRUCT SIMCONNECT_DATA_FACILITY_WAYPOINT : public SIMCONNECT_DATA_FACILITY_AIRPORT +{ + float fMagVar; // Magvar in degrees +}; + +// SIMCONNECT_RECV_WAYPOINT_LIST +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_WAYPOINT_LIST : public SIMCONNECT_RECV_FACILITIES_LIST +{ + SIMCONNECT_FIXEDTYPE_DATAV(SIMCONNECT_DATA_FACILITY_WAYPOINT, rgData, dwArraySize, U1 /*member of UnmanagedType enum*/, SIMCONNECT_DATA_FACILITY_WAYPOINT /*cli type*/); +}; + +// SIMCONNECT_DATA_FACILITY_NDB +SIMCONNECT_REFSTRUCT SIMCONNECT_DATA_FACILITY_NDB : public SIMCONNECT_DATA_FACILITY_WAYPOINT +{ + DWORD fFrequency; // frequency in Hz +}; + +// SIMCONNECT_RECV_NDB_LIST +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_NDB_LIST : public SIMCONNECT_RECV_FACILITIES_LIST +{ + SIMCONNECT_FIXEDTYPE_DATAV(SIMCONNECT_DATA_FACILITY_NDB, rgData, dwArraySize, U1 /*member of UnmanagedType enum*/, SIMCONNECT_DATA_FACILITY_NDB /*cli type*/); +}; + +// SIMCONNECT_DATA_FACILITY_VOR +SIMCONNECT_REFSTRUCT SIMCONNECT_DATA_FACILITY_VOR : public SIMCONNECT_DATA_FACILITY_NDB +{ + DWORD Flags; // SIMCONNECT_VOR_FLAGS + float fLocalizer; // Localizer in degrees + double GlideLat; // Glide Slope Location (deg, deg, meters) + double GlideLon; + double GlideAlt; + float fGlideSlopeAngle; // Glide Slope in degrees +}; + +// SIMCONNECT_RECV_VOR_LIST +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_VOR_LIST : public SIMCONNECT_RECV_FACILITIES_LIST +{ + SIMCONNECT_FIXEDTYPE_DATAV(SIMCONNECT_DATA_FACILITY_VOR, rgData, dwArraySize, U1 /*member of UnmanagedType enum*/, SIMCONNECT_DATA_FACILITY_VOR /*cli type*/); +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_FACILITY_DATA : public SIMCONNECT_RECV +{ + DWORD UserRequestId; + DWORD UniqueRequestId; + DWORD ParentUniqueRequestId; + DWORD Type; + DWORD IsListItem; + DWORD ItemIndex; + DWORD ListSize; + SIMCONNECT_DATAV(Data, Type, ); +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_FACILITY_DATA_END : public SIMCONNECT_RECV +{ + DWORD RequestId; +}; + +SIMCONNECT_STRUCT SIMCONNECT_ICAO +{ + char Type; + SIMCONNECT_STRING(Ident, 8 + 1); + SIMCONNECT_STRING(Region, 2 + 1); + SIMCONNECT_STRING(Airport, 4 + 1); +}; + +// SIMCONNECT_DATA_LATLONALT +SIMCONNECT_STRUCT SIMCONNECT_DATA_LATLONALT +{ + double Latitude; + double Longitude; + double Altitude; +}; + +SIMCONNECT_STRUCT SIMCONNECT_DATA_PBH +{ + float Pitch; + float Bank; + float Heading; +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_FACILITY_MINIMAL +{ + SIMCONNECT_ICAO icao; + SIMCONNECT_DATA_LATLONALT lla; +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_FACILITY_MINIMAL_LIST : public SIMCONNECT_RECV_LIST_TEMPLATE +{ + SIMCONNECT_FIXEDTYPE_DATAV(SIMCONNECT_FACILITY_MINIMAL, rgData, dwArraySize, U1 /*member of UnmanagedType enum*/, SIMCONNECT_FACILITY_MINIMAL /*cli type*/); +}; + +// SIMCONNECT_DATATYPE_INITPOSITION +SIMCONNECT_STRUCT SIMCONNECT_DATA_INITPOSITION +{ + double Latitude; // degrees + double Longitude; // degrees + double Altitude; // feet + double Pitch; // degrees + double Bank; // degrees + double Heading; // degrees + DWORD OnGround; // 1=force to be on the ground + DWORD Airspeed; // knots +}; + + +// SIMCONNECT_DATATYPE_MARKERSTATE +SIMCONNECT_STRUCT SIMCONNECT_DATA_MARKERSTATE +{ + SIMCONNECT_STRING( szMarkerName, 64); + DWORD dwMarkerState; +}; + +// SIMCONNECT_DATATYPE_WAYPOINT +SIMCONNECT_STRUCT SIMCONNECT_DATA_WAYPOINT +{ + double Latitude; // degrees + double Longitude; // degrees + double Altitude; // feet + unsigned long Flags; + double ktsSpeed; // knots + double percentThrottle; +}; + +// SIMCONNECT_DATA_XYZ +SIMCONNECT_STRUCT SIMCONNECT_DATA_XYZ +{ + double x; + double y; + double z; +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_JETWAY_DATA +{ + SIMCONNECT_STRING(AirportIcao, 8); + int ParkingIndex; + SIMCONNECT_DATA_LATLONALT Lla; + SIMCONNECT_DATA_PBH Pbh; + int Status; + int Door; + SIMCONNECT_DATA_XYZ ExitDoorRelativePos; + SIMCONNECT_DATA_XYZ MainHandlePos; + SIMCONNECT_DATA_XYZ SecondaryHandle; + SIMCONNECT_DATA_XYZ WheelGroundLock; + DWORD JetwayObjectId; + DWORD AttachedObjectId; +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_JETWAY_DATA : public SIMCONNECT_RECV_LIST_TEMPLATE +{ + SIMCONNECT_FIXEDTYPE_DATAV(SIMCONNECT_JETWAY_DATA, rgData, dwArraySize, U1 /*member of UnmanagedType enum*/, SIMCONNECT_JETWAY_DATA /*cli type*/); +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_ACTION_CALLBACK : public SIMCONNECT_RECV // when dwID == SIMCONNECT_RECV_ID_ACTION_CALLBACK +{ + SIMCONNECT_STRING(szActionID, MAX_PATH); + DWORD cbRequestId; +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_INPUT_EVENT_DESCRIPTOR +{ + SIMCONNECT_STRING(Name, 64); // Input event name + UINT64 Hash; // Hash + SIMCONNECT_INPUT_EVENT_TYPE eType; +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_ENUMERATE_INPUT_EVENTS : public SIMCONNECT_RECV_LIST_TEMPLATE +{ + SIMCONNECT_FIXEDTYPE_DATAV(SIMCONNECT_INPUT_EVENT_DESCRIPTOR, rgData, dwArraySize, U1 /*member of UnmanagedType enum*/, SIMCONNECT_INPUT_EVENT_DESCRIPTOR /*cli type*/); +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_GET_INPUT_EVENT : public SIMCONNECT_RECV // when dwID == SIMCONNECT_RECV_ID_GET_INPUT_EVENT +{ + DWORD dwRequestID; + SIMCONNECT_INPUT_EVENT_TYPE eType; + SIMCONNECT_DATAV(Value, eType,); +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_SUBSCRIBE_INPUT_EVENT : public SIMCONNECT_RECV +{ + UINT64 Hash; + SIMCONNECT_INPUT_EVENT_TYPE eType; + SIMCONNECT_DATAV(Value, eType,); +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_ENUMERATE_INPUT_EVENT_PARAMS : public SIMCONNECT_RECV +{ + UINT64 Hash; + SIMCONNECT_STRING(Value, MAX_PATH); +}; + + +SIMCONNECT_ENUM SIMCONNECT_POSITION_REFERENTIAL +{ + SIMCONNECT_POSITION_REFERENTIAL_NONE, + SIMCONNECT_POSITION_REFERENTIAL_SIMOBJECT, + SIMCONNECT_POSITION_REFERENTIAL_WORLD, + SIMCONNECT_POSITION_REFERENTIAL_EYEPOINT, + SIMCONNECT_POSITION_REFERENTIAL_SIMOBJECT_DATUM, +}; + +// SIMCONNECT_DATATYPE_CAMERA +SIMCONNECT_STRUCT SIMCONNECT_DATA_CAMERA +{ + SIMCONNECT_DATA_XYZ Position; + SIMCONNECT_POSITION_REFERENTIAL PositionReferential; + DWORD PositionReferentialObjectId; + + SIMCONNECT_DATA_XYZ TargetedPos; + SIMCONNECT_DATA_PBH Pbh; + SIMCONNECT_POSITION_REFERENTIAL RotationReferential; + DWORD RotationReferentialObjectId; + + double Fov; +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_CAMERA_DATA : public SIMCONNECT_RECV +{ + SIMCONNECT_DATA_CAMERA CameraData; +}; + +SIMCONNECT_ENUM SIMCONNECT_CAMERA_WORLD_LOCKER_STATUS +{ + SIMCONNECT_CAMERA_WORLD_LOCKER_STATUS_NONE, + SIMCONNECT_CAMERA_WORLD_LOCKER_STATUS_START, + SIMCONNECT_CAMERA_WORLD_LOCKER_STATUS_SUCCESS, + SIMCONNECT_CAMERA_WORLD_LOCKER_STATUS_CANCEL, + SIMCONNECT_CAMERA_WORLD_LOCKER_STATUS_FAIL +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_CAMERA_WORLD_LOCKER : public SIMCONNECT_RECV +{ + SIMCONNECT_CAMERA_WORLD_LOCKER_STATUS Status; +}; + +SIMCONNECT_ENUM_FLAGS SIMCONNECT_CAMERA_DATA_MASK; + static const DWORD SIMCONNECT_CAMERA_DATA_MASK_NONE = 0; + static const DWORD SIMCONNECT_CAMERA_DATA_MASK_POSITION = 1 << 0; + static const DWORD SIMCONNECT_CAMERA_DATA_MASK_ROTATION = 1 << 1; + static const DWORD SIMCONNECT_CAMERA_DATA_MASK_TARGETED = 1 << 2; + static const DWORD SIMCONNECT_CAMERA_DATA_MASK_FOV = 1 << 3; + static const DWORD SIMCONNECT_CAMERA_DATA_MASK_ALL_ROTATION = SIMCONNECT_CAMERA_DATA_MASK_POSITION | SIMCONNECT_CAMERA_DATA_MASK_ROTATION | SIMCONNECT_CAMERA_DATA_MASK_FOV; + static const DWORD SIMCONNECT_CAMERA_DATA_MASK_ALL_TARGETED = SIMCONNECT_CAMERA_DATA_MASK_POSITION | SIMCONNECT_CAMERA_DATA_MASK_TARGETED | SIMCONNECT_CAMERA_DATA_MASK_FOV; + +SIMCONNECT_ENUM SIMCONNECT_CAMERA_AVAILABILITY +{ + SIMCONNECT_CAMERA_NOT_ACQUIRED, + SIMCONNECT_CAMERA_ACQUIRED, + SIMCONNECT_CAMERA_ACQUIRED_BY_OTHER, + SIMCONNECT_CAMERA_USER_DISABLED +}; + +SIMCONNECT_ENUM_FLAGS SIMCONNECT_CAMERA_FLAG; + static const DWORD SIMCONNECT_CAMERA_FLAG_INTERACTION = 0x01; + static const DWORD SIMCONNECT_CAMERA_FLAG_ABOVE_GROUND = 0x02; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_CAMERA_STATUS : public SIMCONNECT_RECV +{ + DWORD acquiredState = SIMCONNECT_CAMERA_NOT_ACQUIRED; + BOOL bGameControlled = false; +}; + + +SIMCONNECT_REFSTRUCT SIMCONNECT_VERSION_BASE_TYPE +{ + unsigned short Major; + unsigned short Minor; + unsigned short Revision; + unsigned short Build; +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_CONTROLLER_ITEM +{ + SIMCONNECT_STRING(DeviceName, 256); + unsigned int DeviceId; + unsigned int ProductId; + unsigned int CompositeID; + SIMCONNECT_VERSION_BASE_TYPE HardwareVersion; +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_CONTROLLERS_LIST : public SIMCONNECT_RECV_LIST_TEMPLATE +{ + SIMCONNECT_FIXEDTYPE_DATAV(SIMCONNECT_CONTROLLER_ITEM, rgData, dwArraySize, U1 /*member of UnmanagedType enum*/, SIMCONNECT_CONTROLLER_ITEM /*cli type*/); +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_ENUMERATE_SIMOBJECT_LIVERY +{ + SIMCONNECT_STRING(AircraftTitle, 256); + SIMCONNECT_STRING(LiveryName, 256); +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_ENUMERATE_SIMOBJECT_AND_LIVERY_LIST : public SIMCONNECT_RECV_LIST_TEMPLATE +{ + SIMCONNECT_FIXEDTYPE_DATAV(SIMCONNECT_ENUMERATE_SIMOBJECT_LIVERY, rgData, dwArraySize, U1 /*member of UnmanagedType enum*/, SIMCONNECT_ENUMERATE_SIMOBJECT_LIVERY /*cli type*/); +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_FLOW_EVENT : public SIMCONNECT_RECV +{ + SIMCONNECT_FLOW_EVENT FlowEvent; + SIMCONNECT_STRING(FltPath, 256); +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_CAMERA_DEFINITION_ITEM +{ + SIMCONNECT_STRING(Str, 256); +}; + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_CAMERA_DEFINITION_LIST : public SIMCONNECT_RECV_LIST_TEMPLATE +{ + SIMCONNECT_FIXEDTYPE_DATAV(SIMCONNECT_CAMERA_DEFINITION_ITEM, rgData, dwArraySize, U1 /*member of UnmanagedType enum*/, SIMCONNECT_CAMERA_DEFINITION_ITEM /*cli type*/); +}; + + +SIMCONNECT_REFSTRUCT SIMCONNECT_RECV_COMM_BUS : public SIMCONNECT_RECV_LIST_TEMPLATE +{ + DWORD uEventID; + SIMCONNECT_STRINGV(rgData); +}; + + +#pragma pack(pop) + +//---------------------------------------------------------------------------- +// End of Struct definitions +//---------------------------------------------------------------------------- + +#if !defined(SIMCONNECTAPI) + #ifdef _MSFS_WASM + #ifdef __INTELLISENSE__ + #define MODULE_EXPORT + #define SIMCONNECTAPI extern "C" HRESULT + #else + #define MODULE_EXPORT __attribute__( ( visibility( "default" ) ) ) + #define SIMCONNECTAPI extern "C" __attribute__((import_module(SIMCONNECT_WASM_MODULE))) HRESULT + #endif + #else + #define MODULE_EXPORT + #define SIMCONNECTAPI extern "C" HRESULT + #endif +#endif + +#ifdef _USE_WEBASSEMBLY_WASM_RT +typedef void (CALLBACK *DispatchProc)(void* wasmInstance, SIMCONNECT_RECV* pData, DWORD cbData, void* pContext); +#else +typedef void (CALLBACK* DispatchProc)(SIMCONNECT_RECV* pData, DWORD cbData, void* pContext); +#endif // _USE_WEBASSEMBLY_WASM_RT + +SIMCONNECTAPI SimConnect_MapClientEventToSimEvent(HANDLE hSimConnect, SIMCONNECT_CLIENT_EVENT_ID EventID, const char * EventName = ""); +SIMCONNECTAPI SimConnect_TransmitClientEvent(HANDLE hSimConnect, SIMCONNECT_OBJECT_ID ObjectID, SIMCONNECT_CLIENT_EVENT_ID EventID, DWORD dwData, SIMCONNECT_NOTIFICATION_GROUP_ID GroupID, SIMCONNECT_EVENT_FLAG Flags); +SIMCONNECTAPI SimConnect_SetSystemEventState(HANDLE hSimConnect, SIMCONNECT_CLIENT_EVENT_ID EventID, SIMCONNECT_STATE dwState); +SIMCONNECTAPI SimConnect_AddClientEventToNotificationGroup(HANDLE hSimConnect, SIMCONNECT_NOTIFICATION_GROUP_ID GroupID, SIMCONNECT_CLIENT_EVENT_ID EventID, BOOL bMaskable = FALSE); +SIMCONNECTAPI SimConnect_RemoveClientEvent(HANDLE hSimConnect, SIMCONNECT_NOTIFICATION_GROUP_ID GroupID, SIMCONNECT_CLIENT_EVENT_ID EventID); +SIMCONNECTAPI SimConnect_SetNotificationGroupPriority(HANDLE hSimConnect, SIMCONNECT_NOTIFICATION_GROUP_ID GroupID, DWORD uPriority); +SIMCONNECTAPI SimConnect_ClearNotificationGroup(HANDLE hSimConnect, SIMCONNECT_NOTIFICATION_GROUP_ID GroupID); +SIMCONNECTAPI SimConnect_RequestNotificationGroup(HANDLE hSimConnect, SIMCONNECT_NOTIFICATION_GROUP_ID GroupID, DWORD dwReserved = 0, DWORD Flags = 0); +SIMCONNECTAPI SimConnect_AddToDataDefinition(HANDLE hSimConnect, SIMCONNECT_DATA_DEFINITION_ID DefineID, const char * DatumName, const char * UnitsName, SIMCONNECT_DATATYPE DatumType = SIMCONNECT_DATATYPE_FLOAT64, float fEpsilon = 0, DWORD DatumID = SIMCONNECT_UNUSED); +SIMCONNECTAPI SimConnect_ClearDataDefinition(HANDLE hSimConnect, SIMCONNECT_DATA_DEFINITION_ID DefineID); +SIMCONNECTAPI SimConnect_RequestDataOnSimObject(HANDLE hSimConnect, SIMCONNECT_DATA_REQUEST_ID RequestID, SIMCONNECT_DATA_DEFINITION_ID DefineID, SIMCONNECT_OBJECT_ID ObjectID, SIMCONNECT_PERIOD Period, SIMCONNECT_DATA_REQUEST_FLAG Flags = 0, DWORD origin = 0, DWORD interval = 0, DWORD limit = 0); +SIMCONNECTAPI SimConnect_RequestDataOnSimObjectType(HANDLE hSimConnect, SIMCONNECT_DATA_REQUEST_ID RequestID, SIMCONNECT_DATA_DEFINITION_ID DefineID, DWORD dwRadiusMeters, SIMCONNECT_SIMOBJECT_TYPE type); +SIMCONNECTAPI SimConnect_SetDataOnSimObject(HANDLE hSimConnect, SIMCONNECT_DATA_DEFINITION_ID DefineID, SIMCONNECT_OBJECT_ID ObjectID, SIMCONNECT_DATA_SET_FLAG Flags, DWORD ArrayCount, DWORD cbUnitSize, void * pDataSet); +SIMCONNECTAPI SimConnect_MapInputEventToClientEvent(HANDLE hSimConnect, SIMCONNECT_INPUT_GROUP_ID GroupID, const char * szInputDefinition, SIMCONNECT_CLIENT_EVENT_ID DownEventID, DWORD DownValue = 0, SIMCONNECT_CLIENT_EVENT_ID UpEventID = (SIMCONNECT_CLIENT_EVENT_ID)SIMCONNECT_UNUSED, DWORD UpValue = 0, BOOL bMaskable = FALSE); +SIMCONNECTAPI SimConnect_SetInputGroupPriority(HANDLE hSimConnect, SIMCONNECT_INPUT_GROUP_ID GroupID, DWORD uPriority); +SIMCONNECTAPI SimConnect_RemoveInputEvent(HANDLE hSimConnect, SIMCONNECT_INPUT_GROUP_ID GroupID, const char * szInputDefinition); +SIMCONNECTAPI SimConnect_ClearInputGroup(HANDLE hSimConnect, SIMCONNECT_INPUT_GROUP_ID GroupID); +SIMCONNECTAPI SimConnect_SetInputGroupState(HANDLE hSimConnect, SIMCONNECT_INPUT_GROUP_ID GroupID, DWORD dwState); +SIMCONNECTAPI SimConnect_RequestReservedKey(HANDLE hSimConnect, SIMCONNECT_CLIENT_EVENT_ID EventID, const char * szKeyChoice1 = "", const char * szKeyChoice2 = "", const char * szKeyChoice3 = ""); +SIMCONNECTAPI SimConnect_SubscribeToSystemEvent(HANDLE hSimConnect, SIMCONNECT_CLIENT_EVENT_ID EventID, const char * SystemEventName); +SIMCONNECTAPI SimConnect_UnsubscribeFromSystemEvent(HANDLE hSimConnect, SIMCONNECT_CLIENT_EVENT_ID EventID); +SIMCONNECTAPI SimConnect_WeatherRequestInterpolatedObservation(HANDLE hSimConnect, SIMCONNECT_DATA_REQUEST_ID RequestID, float lat, float lon, float alt); +SIMCONNECTAPI SimConnect_WeatherRequestObservationAtStation(HANDLE hSimConnect, SIMCONNECT_DATA_REQUEST_ID RequestID, const char * szICAO); +SIMCONNECTAPI SimConnect_WeatherRequestObservationAtNearestStation(HANDLE hSimConnect, SIMCONNECT_DATA_REQUEST_ID RequestID, float lat, float lon); +SIMCONNECTAPI SimConnect_WeatherCreateStation(HANDLE hSimConnect, SIMCONNECT_DATA_REQUEST_ID RequestID, const char * szICAO, const char * szName, float lat, float lon, float alt); +SIMCONNECTAPI SimConnect_WeatherRemoveStation(HANDLE hSimConnect, SIMCONNECT_DATA_REQUEST_ID RequestID, const char * szICAO); +SIMCONNECTAPI SimConnect_WeatherSetObservation(HANDLE hSimConnect, DWORD Seconds, const char * szMETAR); +SIMCONNECTAPI SimConnect_WeatherSetModeServer(HANDLE hSimConnect, DWORD dwPort, DWORD dwSeconds); +SIMCONNECTAPI SimConnect_WeatherSetModeTheme(HANDLE hSimConnect, const char * szThemeName); +SIMCONNECTAPI SimConnect_WeatherSetModeGlobal(HANDLE hSimConnect); +SIMCONNECTAPI SimConnect_WeatherSetModeCustom(HANDLE hSimConnect); +SIMCONNECTAPI SimConnect_WeatherSetDynamicUpdateRate(HANDLE hSimConnect, DWORD dwRate); +SIMCONNECTAPI SimConnect_WeatherRequestCloudState(HANDLE hSimConnect, SIMCONNECT_DATA_REQUEST_ID RequestID, float minLat, float minLon, float minAlt, float maxLat, float maxLon, float maxAlt, DWORD dwFlags = 0); +SIMCONNECTAPI SimConnect_WeatherCreateThermal(HANDLE hSimConnect, SIMCONNECT_DATA_REQUEST_ID RequestID, float lat, float lon, float alt, float radius, float height, float coreRate = 3.0f, float coreTurbulence = 0.05f, float sinkRate = 3.0f, float sinkTurbulence = 0.2f, float coreSize = 0.4f, float coreTransitionSize = 0.1f, float sinkLayerSize = 0.4f, float sinkTransitionSize = 0.1f); +SIMCONNECTAPI SimConnect_WeatherRemoveThermal(HANDLE hSimConnect, SIMCONNECT_OBJECT_ID ObjectID); +SIMCONNECTAPI SimConnect_AICreateParkedATCAircraft(HANDLE hSimConnect, const char * szContainerTitle, const char * szTailNumber, const char * szAirportID, SIMCONNECT_DATA_REQUEST_ID RequestID); +SIMCONNECTAPI SimConnect_AICreateEnrouteATCAircraft(HANDLE hSimConnect, const char * szContainerTitle, const char * szTailNumber, int iFlightNumber, const char * szFlightPlanPath, double dFlightPlanPosition, BOOL bTouchAndGo, SIMCONNECT_DATA_REQUEST_ID RequestID); +SIMCONNECTAPI SimConnect_AICreateNonATCAircraft(HANDLE hSimConnect, const char * szContainerTitle, const char * szTailNumber, SIMCONNECT_DATA_INITPOSITION InitPos, SIMCONNECT_DATA_REQUEST_ID RequestID); +SIMCONNECTAPI SimConnect_AICreateSimulatedObject(HANDLE hSimConnect, const char * szContainerTitle, SIMCONNECT_DATA_INITPOSITION InitPos, SIMCONNECT_DATA_REQUEST_ID RequestID); +SIMCONNECTAPI SimConnect_AIReleaseControl(HANDLE hSimConnect, SIMCONNECT_OBJECT_ID ObjectID, SIMCONNECT_DATA_REQUEST_ID RequestID); +SIMCONNECTAPI SimConnect_AIRemoveObject(HANDLE hSimConnect, SIMCONNECT_OBJECT_ID ObjectID, SIMCONNECT_DATA_REQUEST_ID RequestID); +SIMCONNECTAPI SimConnect_AISetAircraftFlightPlan(HANDLE hSimConnect, SIMCONNECT_OBJECT_ID ObjectID, const char * szFlightPlanPath, SIMCONNECT_DATA_REQUEST_ID RequestID); +SIMCONNECTAPI SimConnect_ExecuteMissionAction(HANDLE hSimConnect, const GUID guidInstanceId); +SIMCONNECTAPI SimConnect_CompleteCustomMissionAction(HANDLE hSimConnect, const GUID guidInstanceId); +SIMCONNECTAPI SimConnect_Close(HANDLE hSimConnect); +SIMCONNECTAPI SimConnect_RetrieveString(SIMCONNECT_RECV * pData, DWORD cbData, void * pStringV, char ** pszString, DWORD * pcbString); +SIMCONNECTAPI SimConnect_GetLastSentPacketID(HANDLE hSimConnect, DWORD * pdwError); +SIMCONNECTAPI SimConnect_Open(HANDLE * phSimConnect, LPCSTR szName, HWND hWnd, DWORD UserEventWin32, HANDLE hEventHandle, DWORD ConfigIndex); +SIMCONNECTAPI SimConnect_CallDispatch(HANDLE hSimConnect, DispatchProc pfcnDispatch, void * pContext); +SIMCONNECTAPI SimConnect_GetNextDispatch(HANDLE hSimConnect, SIMCONNECT_RECV ** ppData, DWORD * pcbData); +SIMCONNECTAPI SimConnect_RequestResponseTimes(HANDLE hSimConnect, DWORD nCount, float * fElapsedSeconds); +SIMCONNECTAPI SimConnect_InsertString(char * pDest, DWORD cbDest, void ** ppEnd, DWORD * pcbStringV, const char * pSource); +SIMCONNECTAPI SimConnect_CameraSetRelative6DOF(HANDLE hSimConnect, float fDeltaX, float fDeltaY, float fDeltaZ, float fPitchDeg, float fBankDeg, float fHeadingDeg); +SIMCONNECTAPI SimConnect_MenuAddItem(HANDLE hSimConnect, const char * szMenuItem, SIMCONNECT_CLIENT_EVENT_ID MenuEventID, DWORD dwData); +SIMCONNECTAPI SimConnect_MenuDeleteItem(HANDLE hSimConnect, SIMCONNECT_CLIENT_EVENT_ID MenuEventID); +SIMCONNECTAPI SimConnect_MenuAddSubItem(HANDLE hSimConnect, SIMCONNECT_CLIENT_EVENT_ID MenuEventID, const char * szMenuItem, SIMCONNECT_CLIENT_EVENT_ID SubMenuEventID, DWORD dwData); +SIMCONNECTAPI SimConnect_MenuDeleteSubItem(HANDLE hSimConnect, SIMCONNECT_CLIENT_EVENT_ID MenuEventID, const SIMCONNECT_CLIENT_EVENT_ID SubMenuEventID); +SIMCONNECTAPI SimConnect_RequestSystemState(HANDLE hSimConnect, SIMCONNECT_DATA_REQUEST_ID RequestID, const char * szState); +SIMCONNECTAPI SimConnect_SetSystemState(HANDLE hSimConnect, const char * szState, DWORD dwInteger, float fFloat, const char * szString); +SIMCONNECTAPI SimConnect_MapClientDataNameToID(HANDLE hSimConnect, const char * szClientDataName, SIMCONNECT_CLIENT_DATA_ID ClientDataID); +SIMCONNECTAPI SimConnect_CreateClientData(HANDLE hSimConnect, SIMCONNECT_CLIENT_DATA_ID ClientDataID, DWORD dwSize, SIMCONNECT_CREATE_CLIENT_DATA_FLAG Flags); +SIMCONNECTAPI SimConnect_AddToClientDataDefinition(HANDLE hSimConnect, SIMCONNECT_CLIENT_DATA_DEFINITION_ID DefineID, DWORD dwOffset, DWORD dwSizeOrType, float fEpsilon = 0, DWORD DatumID = SIMCONNECT_UNUSED); +SIMCONNECTAPI SimConnect_ClearClientDataDefinition(HANDLE hSimConnect, SIMCONNECT_CLIENT_DATA_DEFINITION_ID DefineID); +SIMCONNECTAPI SimConnect_RequestClientData(HANDLE hSimConnect, SIMCONNECT_CLIENT_DATA_ID ClientDataID, SIMCONNECT_DATA_REQUEST_ID RequestID, SIMCONNECT_CLIENT_DATA_DEFINITION_ID DefineID, SIMCONNECT_CLIENT_DATA_PERIOD Period = SIMCONNECT_CLIENT_DATA_PERIOD_ONCE, SIMCONNECT_CLIENT_DATA_REQUEST_FLAG Flags = 0, DWORD origin = 0, DWORD interval = 0, DWORD limit = 0); +SIMCONNECTAPI SimConnect_SetClientData(HANDLE hSimConnect, SIMCONNECT_CLIENT_DATA_ID ClientDataID, SIMCONNECT_CLIENT_DATA_DEFINITION_ID DefineID, SIMCONNECT_CLIENT_DATA_SET_FLAG Flags, DWORD dwReserved, DWORD cbUnitSize, void * pDataSet); +SIMCONNECTAPI SimConnect_FlightLoad(HANDLE hSimConnect, const char * szFileName); +SIMCONNECTAPI SimConnect_FlightSave(HANDLE hSimConnect, const char * szFileName, const char * szTitle, const char * szDescription, DWORD Flags); +SIMCONNECTAPI SimConnect_FlightPlanLoad(HANDLE hSimConnect, const char * szFileName); +SIMCONNECTAPI SimConnect_Text(HANDLE hSimConnect, SIMCONNECT_TEXT_TYPE type, float fTimeSeconds, SIMCONNECT_CLIENT_EVENT_ID EventID, DWORD cbUnitSize, void * pDataSet); +SIMCONNECTAPI SimConnect_SubscribeToFacilities(HANDLE hSimConnect, SIMCONNECT_FACILITY_LIST_TYPE type, SIMCONNECT_DATA_REQUEST_ID RequestID); +SIMCONNECTAPI SimConnect_UnsubscribeToFacilities(HANDLE hSimConnect, SIMCONNECT_FACILITY_LIST_TYPE type); +SIMCONNECTAPI SimConnect_RequestFacilitiesList(HANDLE hSimConnect, SIMCONNECT_FACILITY_LIST_TYPE type, SIMCONNECT_DATA_REQUEST_ID RequestID); +SIMCONNECTAPI SimConnect_TransmitClientEvent_EX1(HANDLE hSimConnect, SIMCONNECT_OBJECT_ID ObjectID, SIMCONNECT_CLIENT_EVENT_ID EventID, SIMCONNECT_NOTIFICATION_GROUP_ID GroupID, SIMCONNECT_EVENT_FLAG Flags, DWORD dwData0, DWORD dwData1 = 0, DWORD dwData2 = 0, DWORD dwData3 = 0, DWORD dwData4 = 0); +SIMCONNECTAPI SimConnect_AddToFacilityDefinition(HANDLE hSimConnect, SIMCONNECT_DATA_DEFINITION_ID DefineID, const char * FieldName); +SIMCONNECTAPI SimConnect_RequestFacilityData(HANDLE hSimConnect, SIMCONNECT_DATA_DEFINITION_ID DefineID, SIMCONNECT_DATA_REQUEST_ID RequestID, const char * ICAO, const char * Region = ""); +SIMCONNECTAPI SimConnect_SubscribeToFacilities_EX1(HANDLE hSimConnect, SIMCONNECT_FACILITY_LIST_TYPE type, SIMCONNECT_DATA_REQUEST_ID newElemInRangeRequestID, SIMCONNECT_DATA_REQUEST_ID oldElemOutRangeRequestID); +SIMCONNECTAPI SimConnect_UnsubscribeToFacilities_EX1(HANDLE hSimConnect, SIMCONNECT_FACILITY_LIST_TYPE type, bool bUnsubscribeNewInRange, bool bUnsubscribeOldOutRange); +SIMCONNECTAPI SimConnect_RequestFacilitiesList_EX1(HANDLE hSimConnect, SIMCONNECT_FACILITY_LIST_TYPE type, SIMCONNECT_DATA_REQUEST_ID RequestID); +SIMCONNECTAPI SimConnect_RequestFacilityData_EX1(HANDLE hSimConnect, SIMCONNECT_DATA_DEFINITION_ID DefineID, SIMCONNECT_DATA_REQUEST_ID RequestID, const char * ICAO, const char * Region = "", char Type = 0); +SIMCONNECTAPI SimConnect_RequestJetwayData(HANDLE hSimConnect, const char * AirportIcao, DWORD ArrayCount, int * Indexes); +SIMCONNECTAPI SimConnect_EnumerateControllers(HANDLE hSimConnect); +SIMCONNECTAPI SimConnect_MapInputEventToClientEvent_EX1(HANDLE hSimConnect, SIMCONNECT_INPUT_GROUP_ID GroupID, const char * szInputDefinition, SIMCONNECT_CLIENT_EVENT_ID DownEventID, DWORD DownValue = 0, SIMCONNECT_CLIENT_EVENT_ID UpEventID = (SIMCONNECT_CLIENT_EVENT_ID)SIMCONNECT_UNUSED, DWORD UpValue = 0, BOOL bMaskable = FALSE); +SIMCONNECTAPI SimConnect_ExecuteAction(HANDLE hSimConnect, DWORD cbRequestID, const char * szActionID, DWORD cbUnitSize, void * pParamValues); +SIMCONNECTAPI SimConnect_EnumerateInputEvents(HANDLE hSimConnect, SIMCONNECT_DATA_REQUEST_ID RequestID); +SIMCONNECTAPI SimConnect_GetInputEvent(HANDLE hSimConnect, SIMCONNECT_DATA_REQUEST_ID RequestID, UINT64 Hash); +SIMCONNECTAPI SimConnect_SetInputEvent(HANDLE hSimConnect, UINT64 Hash, DWORD cbUnitSize, void * Value); +SIMCONNECTAPI SimConnect_SubscribeInputEvent(HANDLE hSimConnect, UINT64 Hash); +SIMCONNECTAPI SimConnect_UnsubscribeInputEvent(HANDLE hSimConnect, UINT64 Hash); +SIMCONNECTAPI SimConnect_EnumerateInputEventParams(HANDLE hSimConnect, UINT64 Hash); +SIMCONNECTAPI SimConnect_AddFacilityDataDefinitionFilter(HANDLE hSimConnect, SIMCONNECT_DATA_DEFINITION_ID DefineID, const char * szFilterPath, DWORD cbUnitSize, void * pFilterData); +SIMCONNECTAPI SimConnect_ClearAllFacilityDataDefinitionFilters(HANDLE hSimConnect, SIMCONNECT_DATA_DEFINITION_ID DefineID); +SIMCONNECTAPI SimConnect_AICreateParkedATCAircraft_EX1(HANDLE hSimConnect, const char * szContainerTitle, const char * szLivery, const char * szTailNumber, const char * szAirportID, SIMCONNECT_DATA_REQUEST_ID RequestID); +SIMCONNECTAPI SimConnect_AICreateEnrouteATCAircraft_EX1(HANDLE hSimConnect, const char * szContainerTitle, const char * szLivery, const char * szTailNumber, int iFlightNumber, const char * szFlightPlanPath, double dFlightPlanPosition, BOOL bTouchAndGo, SIMCONNECT_DATA_REQUEST_ID RequestID); +SIMCONNECTAPI SimConnect_AICreateNonATCAircraft_EX1(HANDLE hSimConnect, const char * szContainerTitle, const char * szLivery, const char * szTailNumber, SIMCONNECT_DATA_INITPOSITION InitPos, SIMCONNECT_DATA_REQUEST_ID RequestID); +SIMCONNECTAPI SimConnect_AICreateSimulatedObject_EX1(HANDLE hSimConnect, const char * szContainerTitle, const char * szLivery, SIMCONNECT_DATA_INITPOSITION InitPos, SIMCONNECT_DATA_REQUEST_ID RequestID); +SIMCONNECTAPI SimConnect_EnumerateSimObjectsAndLiveries(HANDLE hSimConnect, SIMCONNECT_DATA_REQUEST_ID RequestID, SIMCONNECT_SIMOBJECT_TYPE Type); +SIMCONNECTAPI SimConnect_SubscribeToFlowEvent(HANDLE hSimConnect); +SIMCONNECTAPI SimConnect_UnsubscribeToFlowEvent(HANDLE hSimConnect); +SIMCONNECTAPI SimConnect_RequestAllFacilities(HANDLE hSimConnect, SIMCONNECT_FACILITY_LIST_TYPE type, SIMCONNECT_DATA_REQUEST_ID RequestID); +SIMCONNECTAPI SimConnect_CameraAcquire(HANDLE hSimConnect, const char * ClientId); +SIMCONNECTAPI SimConnect_CameraRelease(HANDLE hSimConnect, const char * CameraDefName); +SIMCONNECTAPI SimConnect_CameraGetStatus(HANDLE hSimConnect); +SIMCONNECTAPI SimConnect_CameraSet(HANDLE hSimConnect, SIMCONNECT_DATA_CAMERA CameraData, DWORD DataMask); +SIMCONNECTAPI SimConnect_CameraGet(HANDLE hSimConnect, DWORD Referential); +SIMCONNECTAPI SimConnect_CameraEnableFlag(HANDLE hSimConnect, DWORD Flag); +SIMCONNECTAPI SimConnect_CameraDisableFlag(HANDLE hSimConnect, DWORD Flag); +SIMCONNECTAPI SimConnect_SubscribeToCameraStatusUpdate(HANDLE hSimConnect); +SIMCONNECTAPI SimConnect_UnsubscribeToCameraStatusUpdate(HANDLE hSimConnect); +SIMCONNECTAPI SimConnect_EnumerateCameraDefinitions(HANDLE hSimConnect); +SIMCONNECTAPI SimConnect_CameraSetUsingCameraDefinition(HANDLE hSimConnect, const char * cameraDefinition); +SIMCONNECTAPI SimConnect_SubscribeToCommBusEvent(HANDLE hSimConnect, SIMCONNECT_CLIENT_EVENT_ID EventID, const char * EventName); +SIMCONNECTAPI SimConnect_UnsubscribeToCommBusEvent(HANDLE hSimConnect, SIMCONNECT_CLIENT_EVENT_ID EventID); +SIMCONNECTAPI SimConnect_CallCommBusEvent(HANDLE hSimConnect, const char * EventName, SIMCONNECT_COMM_BUS_BROADCAST_TO BroadcastTo, DWORD BufferSize, const char * Data); +SIMCONNECTAPI SimConnect_SubscribeToCameraWorldLockerStatusUpdate(HANDLE hSimConnect); +SIMCONNECTAPI SimConnect_UnsubscribeToCameraWorldLockerStatusUpdate(HANDLE hSimConnect); +SIMCONNECTAPI SimConnect_RequestCameraWorldLocker(HANDLE hSimConnect, SIMCONNECT_DATA_XYZ lockerPosition, SIMCONNECT_POSITION_REFERENTIAL referential, DWORD objectId); +SIMCONNECTAPI SimConnect_DeleteCameraWorldLocker(HANDLE hSimConnect); + + +#endif // _SIMCONNECT_H_ diff --git a/simulators/FS2024/libsrc/lib/SimConnect.lib b/simulators/FS2024/libsrc/lib/SimConnect.lib new file mode 100644 index 0000000..ee403f5 Binary files /dev/null and b/simulators/FS2024/libsrc/lib/SimConnect.lib differ diff --git a/simulators/FS2024/src/lib.rs b/simulators/FS2024/src/lib.rs new file mode 100644 index 0000000..b3f1d3d --- /dev/null +++ b/simulators/FS2024/src/lib.rs @@ -0,0 +1,1436 @@ +#![allow(clippy::too_many_arguments, clippy::missing_safety_doc)] +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] + +use std::ffi::CString; +use std::ptr; + +include!(concat!(env!("OUT_DIR"), "/bindings.rs")); + +#[derive(Debug)] +pub enum DispatchResult<'a> { + Null, + Exception(&'a SIMCONNECT_RECV_EXCEPTION), + Open(&'a SIMCONNECT_RECV_OPEN), + Quit(&'a SIMCONNECT_RECV_QUIT), + Event(&'a SIMCONNECT_RECV_EVENT), + EventObjectAddRemove(&'a SIMCONNECT_RECV_EVENT_OBJECT_ADDREMOVE), + EventFilename(&'a SIMCONNECT_RECV_EVENT_FILENAME), + EventFrame(&'a SIMCONNECT_RECV_EVENT_FRAME), + SimObjectData(&'a SIMCONNECT_RECV_SIMOBJECT_DATA), + SimObjectDataByType(&'a SIMCONNECT_RECV_SIMOBJECT_DATA_BYTYPE), + WeatherObservation(&'a SIMCONNECT_RECV_WEATHER_OBSERVATION), + CloudState(&'a SIMCONNECT_RECV_CLOUD_STATE), + AssignedObjectId(&'a SIMCONNECT_RECV_ASSIGNED_OBJECT_ID), + ReservedKey(&'a SIMCONNECT_RECV_RESERVED_KEY), + CustomAction(&'a SIMCONNECT_RECV_CUSTOM_ACTION), + SystemState(&'a SIMCONNECT_RECV_SYSTEM_STATE), + ClientData(&'a SIMCONNECT_RECV_CLIENT_DATA), + EventWeatherMode(&'a SIMCONNECT_RECV_EVENT_WEATHER_MODE), + AirportList(&'a SIMCONNECT_RECV_AIRPORT_LIST), + VorList(&'a SIMCONNECT_RECV_VOR_LIST), + NdbList(&'a SIMCONNECT_RECV_NDB_LIST), + WaypointList(&'a SIMCONNECT_RECV_WAYPOINT_LIST), + EventMultiplayerServerStarted(&'a SIMCONNECT_RECV_EVENT_MULTIPLAYER_SERVER_STARTED), + EventMultiplayerClientStarted(&'a SIMCONNECT_RECV_EVENT_MULTIPLAYER_CLIENT_STARTED), + EventMultiplayerSessionEnded(&'a SIMCONNECT_RECV_EVENT_MULTIPLAYER_SESSION_ENDED), + EventRaceEnd(&'a SIMCONNECT_RECV_EVENT_RACE_END), + EventRaceLap(&'a SIMCONNECT_RECV_EVENT_RACE_LAP), + EventEx1(&'a SIMCONNECT_RECV_EVENT_EX1), + FacilityData(&'a SIMCONNECT_RECV_FACILITY_DATA), + FacilityDataEnd(&'a SIMCONNECT_RECV_FACILITY_DATA_END), + FacilityMinimalList(&'a SIMCONNECT_RECV_FACILITY_MINIMAL_LIST), + JetwayData(&'a SIMCONNECT_RECV_JETWAY_DATA), + ActionCallback(&'a SIMCONNECT_RECV_ACTION_CALLBACK), + EnumerateInputEvents(&'a SIMCONNECT_RECV_ENUMERATE_INPUT_EVENTS), + GetInputEvent(&'a SIMCONNECT_RECV_GET_INPUT_EVENT), + SubscribeInputEvent(&'a SIMCONNECT_RECV_SUBSCRIBE_INPUT_EVENT), + EnumerateInputEventParams(&'a SIMCONNECT_RECV_ENUMERATE_INPUT_EVENT_PARAMS), + ControllersList(&'a SIMCONNECT_RECV_CONTROLLERS_LIST), + EnumerateSimObjectAndLiveryList(&'a SIMCONNECT_RECV_ENUMERATE_SIMOBJECT_AND_LIVERY_LIST), + FlowEvent(&'a SIMCONNECT_RECV_FLOW_EVENT), + CameraData(&'a SIMCONNECT_RECV_CAMERA_DATA), + CameraStatus(&'a SIMCONNECT_RECV_CAMERA_STATUS), + CameraDefinitionList(&'a SIMCONNECT_RECV_CAMERA_DEFINITION_LIST), + CommBus(&'a SIMCONNECT_RECV_COMM_BUS), + CameraWorldLocker(&'a SIMCONNECT_RECV_CAMERA_WORLD_LOCKER), +} + +#[derive(Debug)] +pub struct SimConnector { + handle: HANDLE, +} + +impl Default for SimConnector { + fn default() -> Self { + Self { handle: ptr::null_mut() } + } +} + +impl SimConnector { + pub fn new() -> Self { + Self::default() + } + + // ==================== Connection & Lifecycle ==================== + + pub fn connect(&mut self, program_name: &str) -> bool { + let name = cstring(program_name); + + unsafe { + SimConnect_Open( + &mut self.handle, + name.as_ptr(), + ptr::null_mut(), + 0, + ptr::null_mut(), + 0, + ) == 0 + } + } + + pub fn close(&mut self) -> bool { + if self.handle.is_null() { + return true; + } + let result = unsafe { SimConnect_Close(self.handle) == 0 }; + self.handle = ptr::null_mut(); + result + } + + // ==================== Data Definition ==================== + + pub fn add_data_definition( + &self, + define_id: SIMCONNECT_DATA_DEFINITION_ID, + datum_name: &str, + units_name: &str, + datum_type: SIMCONNECT_DATATYPE, + epsilon: f32, + datum_id: DWORD, + ) -> bool { + let name = cstring(datum_name); + let units = cstring(units_name); + + unsafe { + SimConnect_AddToDataDefinition( + self.handle, + define_id, + name.as_ptr(), + units.as_ptr(), + datum_type, + epsilon, + datum_id, + ) == 0 + } + } + + pub fn clear_data_definition(&self, define_id: SIMCONNECT_DATA_DEFINITION_ID) -> bool { + unsafe { SimConnect_ClearDataDefinition(self.handle, define_id) == 0 } + } + + // ==================== Events ==================== + + pub fn map_client_event_to_sim_event( + &self, + event_id: SIMCONNECT_CLIENT_EVENT_ID, + event_name: &str, + ) -> bool { + let name = cstring(event_name); + unsafe { SimConnect_MapClientEventToSimEvent(self.handle, event_id, name.as_ptr()) == 0 } + } + + pub fn subscribe_to_system_event( + &self, + event_id: SIMCONNECT_CLIENT_EVENT_ID, + event_name: &str, + ) -> bool { + let name = cstring(event_name); + unsafe { + SimConnect_SubscribeToSystemEvent(self.handle, event_id, name.as_ptr()) == 0 + } + } + + pub fn unsubscribe_from_system_event(&self, event_id: SIMCONNECT_CLIENT_EVENT_ID) -> bool { + unsafe { SimConnect_UnsubscribeFromSystemEvent(self.handle, event_id) == 0 } + } + + pub fn set_system_event_state( + &self, + event_id: SIMCONNECT_CLIENT_EVENT_ID, + state: SIMCONNECT_STATE, + ) -> bool { + unsafe { SimConnect_SetSystemEventState(self.handle, event_id, state) == 0 } + } + + pub fn transmit_client_event( + &self, + object_id: SIMCONNECT_OBJECT_ID, + event_id: SIMCONNECT_CLIENT_EVENT_ID, + dw_data: DWORD, + group_id: SIMCONNECT_NOTIFICATION_GROUP_ID, + flags: SIMCONNECT_EVENT_FLAG, + ) -> bool { + unsafe { + SimConnect_TransmitClientEvent( + self.handle, + object_id, + event_id, + dw_data, + group_id, + flags, + ) == 0 + } + } + + pub fn add_client_event_to_notification_group( + &self, + group_id: SIMCONNECT_NOTIFICATION_GROUP_ID, + event_id: SIMCONNECT_CLIENT_EVENT_ID, + maskable: bool, + ) -> bool { + unsafe { + SimConnect_AddClientEventToNotificationGroup( + self.handle, + group_id, + event_id, + maskable as i32, + ) == 0 + } + } + + pub fn set_notification_group_priority( + &self, + group_id: SIMCONNECT_NOTIFICATION_GROUP_ID, + priority: DWORD, + ) -> bool { + unsafe { + SimConnect_SetNotificationGroupPriority(self.handle, group_id, priority) == 0 + } + } + + pub fn remove_client_event( + &self, + group_id: SIMCONNECT_NOTIFICATION_GROUP_ID, + event_id: SIMCONNECT_CLIENT_EVENT_ID, + ) -> bool { + unsafe { SimConnect_RemoveClientEvent(self.handle, group_id, event_id) == 0 } + } + + pub fn clear_notification_group(&self, group_id: SIMCONNECT_NOTIFICATION_GROUP_ID) -> bool { + unsafe { SimConnect_ClearNotificationGroup(self.handle, group_id) == 0 } + } + + pub fn request_notification_group( + &self, + group_id: SIMCONNECT_NOTIFICATION_GROUP_ID, + reserved: DWORD, + flags: DWORD, + ) -> bool { + unsafe { + SimConnect_RequestNotificationGroup(self.handle, group_id, reserved, flags) == 0 + } + } + + pub fn transmit_client_event_ex1( + &self, + object_id: SIMCONNECT_OBJECT_ID, + event_id: SIMCONNECT_CLIENT_EVENT_ID, + group_id: SIMCONNECT_NOTIFICATION_GROUP_ID, + flags: SIMCONNECT_EVENT_FLAG, + data0: DWORD, + data1: DWORD, + data2: DWORD, + data3: DWORD, + data4: DWORD, + ) -> bool { + unsafe { + SimConnect_TransmitClientEvent_EX1( + self.handle, + object_id, + event_id, + group_id, + flags, + data0, + data1, + data2, + data3, + data4, + ) == 0 + } + } + + pub fn request_reserved_key( + &self, + event_id: SIMCONNECT_CLIENT_EVENT_ID, + key_choice1: &str, + key_choice2: &str, + key_choice3: &str, + ) -> bool { + let k1 = cstring(key_choice1); + let k2 = cstring(key_choice2); + let k3 = cstring(key_choice3); + + unsafe { + SimConnect_RequestReservedKey( + self.handle, + event_id, + k1.as_ptr(), + k2.as_ptr(), + k3.as_ptr(), + ) == 0 + } + } + + // ==================== Input Events ==================== + + pub fn map_input_event_to_client_event( + &self, + group_id: SIMCONNECT_INPUT_GROUP_ID, + input_definition: &str, + down_event: SIMCONNECT_CLIENT_EVENT_ID, + down_return_value: DWORD, + up_event: SIMCONNECT_CLIENT_EVENT_ID, + up_return_value: DWORD, + maskable: bool, + ) -> bool { + let input = cstring(input_definition); + unsafe { + SimConnect_MapInputEventToClientEvent( + self.handle, + group_id, + input.as_ptr(), + down_event, + down_return_value, + up_event, + up_return_value, + maskable as i32, + ) == 0 + } + } + + pub fn map_input_event_to_client_event_ex1( + &self, + group_id: SIMCONNECT_INPUT_GROUP_ID, + input_definition: &str, + down_event: SIMCONNECT_CLIENT_EVENT_ID, + down_return_value: DWORD, + up_event: SIMCONNECT_CLIENT_EVENT_ID, + up_return_value: DWORD, + maskable: bool, + ) -> bool { + let input = cstring(input_definition); + unsafe { + SimConnect_MapInputEventToClientEvent_EX1( + self.handle, + group_id, + input.as_ptr(), + down_event, + down_return_value, + up_event, + up_return_value, + maskable as i32, + ) == 0 + } + } + + pub fn set_input_group_state(&self, group_id: SIMCONNECT_INPUT_GROUP_ID, state: DWORD) -> bool { + unsafe { SimConnect_SetInputGroupState(self.handle, group_id, state) == 0 } + } + + pub fn set_input_priority(&self, group_id: SIMCONNECT_INPUT_GROUP_ID, priority: DWORD) -> bool { + unsafe { SimConnect_SetInputGroupPriority(self.handle, group_id, priority) == 0 } + } + + pub fn remove_input_event( + &self, + group_id: SIMCONNECT_INPUT_GROUP_ID, + input_definition: &str, + ) -> bool { + let input = cstring(input_definition); + unsafe { + SimConnect_RemoveInputEvent(self.handle, group_id, input.as_ptr()) == 0 + } + } + + pub fn clear_input_group(&self, group_id: SIMCONNECT_INPUT_GROUP_ID) -> bool { + unsafe { SimConnect_ClearInputGroup(self.handle, group_id) == 0 } + } + + // ==================== Data Requests ==================== + + pub fn request_data_on_sim_object( + &self, + request_id: SIMCONNECT_DATA_REQUEST_ID, + define_id: SIMCONNECT_DATA_DEFINITION_ID, + object_id: SIMCONNECT_OBJECT_ID, + period: SIMCONNECT_PERIOD, + flags: SIMCONNECT_DATA_REQUEST_FLAG, + origin: DWORD, + interval: DWORD, + limit: DWORD, + ) -> bool { + unsafe { + SimConnect_RequestDataOnSimObject( + self.handle, + request_id, + define_id, + object_id, + period, + flags, + origin, + interval, + limit, + ) == 0 + } + } + + pub fn request_data_on_sim_object_type( + &self, + request_id: SIMCONNECT_DATA_REQUEST_ID, + define_id: SIMCONNECT_DATA_DEFINITION_ID, + radius_in_meters: DWORD, + object_type: SIMCONNECT_SIMOBJECT_TYPE, + ) -> bool { + unsafe { + SimConnect_RequestDataOnSimObjectType( + self.handle, + request_id, + define_id, + radius_in_meters, + object_type, + ) == 0 + } + } + + pub unsafe fn set_data_on_sim_object( + &self, + define_id: SIMCONNECT_DATA_DEFINITION_ID, + object_id: SIMCONNECT_OBJECT_ID, + flags: SIMCONNECT_DATA_SET_FLAG, + array_count: DWORD, + size: DWORD, + pntr: *mut std::os::raw::c_void, + ) -> bool { + unsafe { + SimConnect_SetDataOnSimObject( + self.handle, define_id, object_id, flags, array_count, size, pntr, + ) == 0 + } + } + + // ==================== Client Data ==================== + + pub fn create_client_data( + &self, + data_id: SIMCONNECT_CLIENT_DATA_ID, + size: DWORD, + flags: SIMCONNECT_CREATE_CLIENT_DATA_FLAG, + ) -> bool { + unsafe { SimConnect_CreateClientData(self.handle, data_id, size, flags) == 0 } + } + + pub fn map_client_data_name_to_id( + &self, + client_data_name: &str, + data_id: SIMCONNECT_CLIENT_DATA_ID, + ) -> bool { + let name = cstring(client_data_name); + unsafe { + SimConnect_MapClientDataNameToID(self.handle, name.as_ptr(), data_id) == 0 + } + } + + pub fn add_to_client_data_definition( + &self, + define_id: SIMCONNECT_DATA_DEFINITION_ID, + offset: DWORD, + size_or_type: DWORD, + epsilon: f32, + datum_id: DWORD, + ) -> bool { + unsafe { + SimConnect_AddToClientDataDefinition( + self.handle, define_id, offset, size_or_type, epsilon, datum_id, + ) == 0 + } + } + + pub fn clear_client_data_definition(&self, define_id: SIMCONNECT_DATA_DEFINITION_ID) -> bool { + unsafe { SimConnect_ClearClientDataDefinition(self.handle, define_id) == 0 } + } + + pub fn request_client_data( + &self, + data_id: SIMCONNECT_CLIENT_DATA_ID, + request_id: SIMCONNECT_DATA_REQUEST_ID, + define_id: SIMCONNECT_DATA_DEFINITION_ID, + period: SIMCONNECT_CLIENT_DATA_PERIOD, + flags: SIMCONNECT_CLIENT_DATA_REQUEST_FLAG, + origin: DWORD, + interval: DWORD, + limit: DWORD, + ) -> bool { + unsafe { + SimConnect_RequestClientData( + self.handle, + data_id, + request_id, + define_id, + period, + flags, + origin, + interval, + limit, + ) == 0 + } + } + + pub unsafe fn set_client_data( + &self, + data_id: SIMCONNECT_CLIENT_DATA_ID, + define_id: SIMCONNECT_DATA_DEFINITION_ID, + flags: DWORD, + reserved: DWORD, + unit_size: DWORD, + data_set: *mut std::os::raw::c_void, + ) -> bool { + unsafe { + SimConnect_SetClientData( + self.handle, data_id, define_id, flags, reserved, unit_size, data_set, + ) == 0 + } + } + + // ==================== AI Objects ==================== + + pub fn ai_create_parked_atc_aircraft( + &self, + container_title: &str, + tail_number: &str, + airport_id: &str, + request_id: SIMCONNECT_DATA_REQUEST_ID, + ) -> bool { + let title = cstring(container_title); + let tail = cstring(tail_number); + let airport = cstring(airport_id); + + unsafe { + SimConnect_AICreateParkedATCAircraft( + self.handle, + title.as_ptr(), + tail.as_ptr(), + airport.as_ptr(), + request_id, + ) == 0 + } + } + + pub fn ai_create_parked_atc_aircraft_ex1( + &self, + container_title: &str, + livery: &str, + tail_number: &str, + airport_id: &str, + request_id: SIMCONNECT_DATA_REQUEST_ID, + ) -> bool { + let title = cstring(container_title); + let liv = cstring(livery); + let tail = cstring(tail_number); + let airport = cstring(airport_id); + + unsafe { + SimConnect_AICreateParkedATCAircraft_EX1( + self.handle, + title.as_ptr(), + liv.as_ptr(), + tail.as_ptr(), + airport.as_ptr(), + request_id, + ) == 0 + } + } + + pub fn ai_create_enroute_atc_aircraft( + &self, + container_title: &str, + tail_number: &str, + flight_number: i32, + flight_plan_path: &str, + flight_plan_position: f64, + touch_and_go: bool, + request_id: SIMCONNECT_DATA_REQUEST_ID, + ) -> bool { + let title = cstring(container_title); + let tail = cstring(tail_number); + let plan = cstring(flight_plan_path); + + unsafe { + SimConnect_AICreateEnrouteATCAircraft( + self.handle, + title.as_ptr(), + tail.as_ptr(), + flight_number, + plan.as_ptr(), + flight_plan_position, + touch_and_go as i32, + request_id, + ) == 0 + } + } + + pub fn ai_create_enroute_atc_aircraft_ex1( + &self, + container_title: &str, + livery: &str, + tail_number: &str, + flight_number: i32, + flight_plan_path: &str, + flight_plan_position: f64, + touch_and_go: bool, + request_id: SIMCONNECT_DATA_REQUEST_ID, + ) -> bool { + let title = cstring(container_title); + let liv = cstring(livery); + let tail = cstring(tail_number); + let plan = cstring(flight_plan_path); + + unsafe { + SimConnect_AICreateEnrouteATCAircraft_EX1( + self.handle, + title.as_ptr(), + liv.as_ptr(), + tail.as_ptr(), + flight_number, + plan.as_ptr(), + flight_plan_position, + touch_and_go as i32, + request_id, + ) == 0 + } + } + + pub fn ai_create_non_atc_aircraft( + &self, + container_title: &str, + tail_number: &str, + init_pos: SIMCONNECT_DATA_INITPOSITION, + request_id: SIMCONNECT_DATA_REQUEST_ID, + ) -> bool { + let title = cstring(container_title); + let tail = cstring(tail_number); + + unsafe { + SimConnect_AICreateNonATCAircraft( + self.handle, title.as_ptr(), tail.as_ptr(), init_pos, request_id, + ) == 0 + } + } + + pub fn ai_create_non_atc_aircraft_ex1( + &self, + container_title: &str, + livery: &str, + tail_number: &str, + init_pos: SIMCONNECT_DATA_INITPOSITION, + request_id: SIMCONNECT_DATA_REQUEST_ID, + ) -> bool { + let title = cstring(container_title); + let liv = cstring(livery); + let tail = cstring(tail_number); + + unsafe { + SimConnect_AICreateNonATCAircraft_EX1( + self.handle, + title.as_ptr(), + liv.as_ptr(), + tail.as_ptr(), + init_pos, + request_id, + ) == 0 + } + } + + pub fn ai_create_simulated_object( + &self, + container_title: &str, + init_pos: SIMCONNECT_DATA_INITPOSITION, + request_id: SIMCONNECT_DATA_REQUEST_ID, + ) -> bool { + let title = cstring(container_title); + unsafe { + SimConnect_AICreateSimulatedObject(self.handle, title.as_ptr(), init_pos, request_id) == 0 + } + } + + pub fn ai_create_simulated_object_ex1( + &self, + container_title: &str, + livery: &str, + init_pos: SIMCONNECT_DATA_INITPOSITION, + request_id: SIMCONNECT_DATA_REQUEST_ID, + ) -> bool { + let title = cstring(container_title); + let liv = cstring(livery); + + unsafe { + SimConnect_AICreateSimulatedObject_EX1( + self.handle, + title.as_ptr(), + liv.as_ptr(), + init_pos, + request_id, + ) == 0 + } + } + + pub fn ai_release_control( + &self, + object_id: SIMCONNECT_OBJECT_ID, + request_id: SIMCONNECT_DATA_REQUEST_ID, + ) -> bool { + unsafe { SimConnect_AIReleaseControl(self.handle, object_id, request_id) == 0 } + } + + pub fn ai_remove_object( + &self, + object_id: SIMCONNECT_OBJECT_ID, + request_id: SIMCONNECT_DATA_REQUEST_ID, + ) -> bool { + unsafe { SimConnect_AIRemoveObject(self.handle, object_id, request_id) == 0 } + } + + pub fn ai_set_aircraft_flight_plan( + &self, + object_id: SIMCONNECT_OBJECT_ID, + flight_plan_path: &str, + request_id: SIMCONNECT_DATA_REQUEST_ID, + ) -> bool { + let plan = cstring(flight_plan_path); + unsafe { + SimConnect_AISetAircraftFlightPlan( + self.handle, object_id, plan.as_ptr(), request_id, + ) == 0 + } + } + + // ==================== Weather ==================== + + pub fn weather_request_interpolated_observation( + &self, + request_id: SIMCONNECT_DATA_REQUEST_ID, + lat: f32, + lon: f32, + alt: f32, + ) -> bool { + unsafe { + SimConnect_WeatherRequestInterpolatedObservation(self.handle, request_id, lat, lon, alt) == 0 + } + } + + pub fn weather_request_observation_at_station( + &self, + request_id: SIMCONNECT_DATA_REQUEST_ID, + station: &str, + ) -> bool { + let station = cstring(station); + unsafe { + SimConnect_WeatherRequestObservationAtStation(self.handle, request_id, station.as_ptr()) == 0 + } + } + + pub fn weather_request_observation_at_nearest_station( + &self, + request_id: SIMCONNECT_DATA_REQUEST_ID, + lat: f32, + lon: f32, + ) -> bool { + unsafe { + SimConnect_WeatherRequestObservationAtNearestStation(self.handle, request_id, lat, lon) == 0 + } + } + + pub fn weather_create_station( + &self, + request_id: SIMCONNECT_DATA_REQUEST_ID, + icao: &str, + name: &str, + lat: f32, + lon: f32, + alt: f32, + ) -> bool { + let icao_c = cstring(icao); + let name_c = cstring(name); + + unsafe { + SimConnect_WeatherCreateStation( + self.handle, + request_id, + icao_c.as_ptr(), + name_c.as_ptr(), + lat, + lon, + alt, + ) == 0 + } + } + + pub fn weather_remove_station(&self, request_id: SIMCONNECT_DATA_REQUEST_ID, station: &str) -> bool { + let station = cstring(station); + unsafe { + SimConnect_WeatherRemoveStation(self.handle, request_id, station.as_ptr()) == 0 + } + } + + pub fn weather_set_observation(&self, seconds: DWORD, observation: &str) -> bool { + let obs = cstring(observation); + unsafe { + SimConnect_WeatherSetObservation(self.handle, seconds, obs.as_ptr()) == 0 + } + } + + pub fn weather_set_mode_server(&self, port: DWORD, seconds: DWORD) -> bool { + unsafe { SimConnect_WeatherSetModeServer(self.handle, port, seconds) == 0 } + } + + pub fn weather_set_mode_theme(&self, theme_name: &str) -> bool { + let theme = cstring(theme_name); + unsafe { SimConnect_WeatherSetModeTheme(self.handle, theme.as_ptr()) == 0 } + } + + pub fn weather_set_mode_global(&self) -> bool { + unsafe { SimConnect_WeatherSetModeGlobal(self.handle) == 0 } + } + + pub fn weather_set_mode_custom(&self) -> bool { + unsafe { SimConnect_WeatherSetModeCustom(self.handle) == 0 } + } + + pub fn weather_set_dynamic_update_rate(&self, rate: DWORD) -> bool { + unsafe { SimConnect_WeatherSetDynamicUpdateRate(self.handle, rate) == 0 } + } + + pub fn weather_request_cloud_state( + &self, + request_id: SIMCONNECT_DATA_REQUEST_ID, + min_x: f32, + min_y: f32, + min_z: f32, + max_x: f32, + max_y: f32, + max_z: f32, + flags: DWORD, + ) -> bool { + unsafe { + SimConnect_WeatherRequestCloudState( + self.handle, request_id, min_x, min_y, min_z, max_x, max_y, max_z, flags, + ) == 0 + } + } + + pub fn weather_create_thermal( + &self, + request_id: SIMCONNECT_DATA_REQUEST_ID, + lat: f32, + lon: f32, + alt: f32, + radius: f32, + height: f32, + core_rate: f32, + core_turbulence: f32, + sink_rate: f32, + sink_turbulence: f32, + core_size: f32, + core_transition_size: f32, + sink_layer_size: f32, + sink_transition_size: f32, + ) -> bool { + unsafe { + SimConnect_WeatherCreateThermal( + self.handle, + request_id, + lat, + lon, + alt, + radius, + height, + core_rate, + core_turbulence, + sink_rate, + sink_turbulence, + core_size, + core_transition_size, + sink_layer_size, + sink_transition_size, + ) == 0 + } + } + + pub fn weather_remove_thermal(&self, object_id: SIMCONNECT_OBJECT_ID) -> bool { + unsafe { SimConnect_WeatherRemoveThermal(self.handle, object_id) == 0 } + } + + // ==================== Mission & System ==================== + + pub fn execute_mission_action(&self, instance_id: GUID) -> bool { + unsafe { SimConnect_ExecuteMissionAction(self.handle, instance_id) == 0 } + } + + pub fn complete_custom_mission_action(&self, instance_id: GUID) -> bool { + unsafe { SimConnect_CompleteCustomMissionAction(self.handle, instance_id) == 0 } + } + + pub fn request_system_state(&self, request_id: SIMCONNECT_DATA_REQUEST_ID, state: &str) -> bool { + let state = cstring(state); + unsafe { SimConnect_RequestSystemState(self.handle, request_id, state.as_ptr()) == 0 } + } + + pub fn set_system_state(&self, state: &str, integer: DWORD, float_val: f32, string_val: &str) -> bool { + let state_c = cstring(state); + let string_c = cstring(string_val); + + unsafe { + SimConnect_SetSystemState( + self.handle, + state_c.as_ptr(), + integer, + float_val, + string_c.as_ptr(), + ) == 0 + } + } + + pub fn flight_load(&self, file_name: &str) -> bool { + let name = cstring(file_name); + unsafe { SimConnect_FlightLoad(self.handle, name.as_ptr()) == 0 } + } + + pub fn flight_save(&self, file_name: &str, title: &str, description: &str, flags: DWORD) -> bool { + let name = cstring(file_name); + let t = cstring(title); + let d = cstring(description); + unsafe { SimConnect_FlightSave(self.handle, name.as_ptr(), t.as_ptr(), d.as_ptr(), flags) == 0 } + } + + pub fn flight_plan_load(&self, file_name: &str) -> bool { + let name = cstring(file_name); + unsafe { SimConnect_FlightPlanLoad(self.handle, name.as_ptr()) == 0 } + } + + // ==================== Facilities ==================== + + pub fn subscribe_to_facilities( + &self, + list_type: SIMCONNECT_FACILITY_LIST_TYPE, + request_id: SIMCONNECT_DATA_REQUEST_ID, + ) -> bool { + unsafe { SimConnect_SubscribeToFacilities(self.handle, list_type, request_id) == 0 } + } + + pub fn unsubscribe_to_facilities(&self, list_type: SIMCONNECT_FACILITY_LIST_TYPE) -> bool { + unsafe { SimConnect_UnsubscribeToFacilities(self.handle, list_type) == 0 } + } + + pub fn request_facilities_list( + &self, + list_type: SIMCONNECT_FACILITY_LIST_TYPE, + request_id: SIMCONNECT_DATA_REQUEST_ID, + ) -> bool { + unsafe { SimConnect_RequestFacilitiesList(self.handle, list_type, request_id) == 0 } + } + + pub fn request_all_facilities( + &self, + list_type: SIMCONNECT_FACILITY_LIST_TYPE, + request_id: SIMCONNECT_DATA_REQUEST_ID, + ) -> bool { + unsafe { SimConnect_RequestAllFacilities(self.handle, list_type, request_id) == 0 } + } + + pub fn add_to_facility_definition(&self, define_id: SIMCONNECT_DATA_DEFINITION_ID, field_name: &str) -> bool { + let field = cstring(field_name); + unsafe { SimConnect_AddToFacilityDefinition(self.handle, define_id, field.as_ptr()) == 0 } + } + + pub fn request_facility_data( + &self, + define_id: SIMCONNECT_DATA_DEFINITION_ID, + request_id: SIMCONNECT_DATA_REQUEST_ID, + icao: &str, + region: Option<&str>, + ) -> bool { + let icao = cstring(icao); + let region = region.map(|s| cstring(s)); + unsafe { + SimConnect_RequestFacilityData( + self.handle, + define_id, + request_id, + icao.as_ptr(), + region.as_ref().map_or(ptr::null(), |s| s.as_ptr()), + ) == 0 + } + } + + pub fn subscribe_to_facilities_ex1( + &self, + list_type: SIMCONNECT_FACILITY_LIST_TYPE, + new_in_range_request_id: SIMCONNECT_DATA_REQUEST_ID, + old_out_of_range_request_id: SIMCONNECT_DATA_REQUEST_ID, + ) -> bool { + unsafe { + SimConnect_SubscribeToFacilities_EX1( + self.handle, + list_type, + new_in_range_request_id, + old_out_of_range_request_id, + ) == 0 + } + } + + pub fn unsubscribe_to_facilities_ex1( + &self, + list_type: SIMCONNECT_FACILITY_LIST_TYPE, + unsubscribe_new_in_range: bool, + unsubscribe_old_out_of_range: bool, + ) -> bool { + unsafe { + SimConnect_UnsubscribeToFacilities_EX1( + self.handle, + list_type, + unsubscribe_new_in_range, + unsubscribe_old_out_of_range, + ) == 0 + } + } + + pub fn request_facilities_list_ex1( + &self, + list_type: SIMCONNECT_FACILITY_LIST_TYPE, + request_id: SIMCONNECT_DATA_REQUEST_ID, + ) -> bool { + unsafe { + SimConnect_RequestFacilitiesList_EX1(self.handle, list_type, request_id) == 0 + } + } + + pub fn request_facility_data_ex1( + &self, + define_id: SIMCONNECT_DATA_DEFINITION_ID, + request_id: SIMCONNECT_DATA_REQUEST_ID, + icao: &str, + region: Option<&str>, + type_: Option, + ) -> bool { + let icao = cstring(icao); + let region = region.map(|s| cstring(s)); + unsafe { + SimConnect_RequestFacilityData_EX1( + self.handle, + define_id, + request_id, + icao.as_ptr(), + region.as_ref().map_or(ptr::null(), |s| s.as_ptr()), + type_.unwrap_or(0) as ::std::os::raw::c_char, + ) == 0 + } + } + + pub unsafe fn request_jetway_data( + &self, + airport_icao: &str, + array_count: DWORD, + indexes: *mut i32, + ) -> bool { + let icao = cstring(airport_icao); + unsafe { + SimConnect_RequestJetwayData(self.handle, icao.as_ptr(), array_count, indexes) == 0 + } + } + + pub fn add_facility_data_definition_filter( + &self, + define_id: SIMCONNECT_DATA_DEFINITION_ID, + filter_path: &str, + filter_data: *const std::os::raw::c_void, + cb_unit_size: DWORD, + ) -> bool { + let path = cstring(filter_path); + unsafe { + SimConnect_AddFacilityDataDefinitionFilter( + self.handle, + define_id, + path.as_ptr(), + cb_unit_size, + filter_data as *mut _, + ) == 0 + } + } + + pub fn clear_all_facility_data_definition_filters( + &self, + define_id: SIMCONNECT_DATA_DEFINITION_ID, + ) -> bool { + unsafe { + SimConnect_ClearAllFacilityDataDefinitionFilters(self.handle, define_id) == 0 + } + } + + // ==================== Camera ==================== + + pub fn camera_set_relative_6dof( + &self, + delta_x: f32, + delta_y: f32, + delta_z: f32, + pitch: f32, + bank: f32, + heading: f32, + ) -> bool { + unsafe { + SimConnect_CameraSetRelative6DOF( + self.handle, delta_x, delta_y, delta_z, pitch, bank, heading, + ) == 0 + } + } + + pub fn camera_acquire(&self, client_id: &str) -> bool { + let id = cstring(client_id); + unsafe { SimConnect_CameraAcquire(self.handle, id.as_ptr()) == 0 } + } + + pub fn camera_release(&self, camera_def_name: &str) -> bool { + let name = cstring(camera_def_name); + unsafe { SimConnect_CameraRelease(self.handle, name.as_ptr()) == 0 } + } + + pub fn camera_get_status(&self) -> bool { + unsafe { SimConnect_CameraGetStatus(self.handle) == 0 } + } + + pub unsafe fn camera_set(&self, camera_data: SIMCONNECT_DATA_CAMERA, data_mask: DWORD) -> bool { + unsafe { SimConnect_CameraSet(self.handle, camera_data, data_mask) == 0 } + } + + pub fn camera_get(&self, referential: DWORD) -> bool { + unsafe { SimConnect_CameraGet(self.handle, referential) == 0 } + } + + pub fn camera_enable_flag(&self, flag: DWORD) -> bool { + unsafe { SimConnect_CameraEnableFlag(self.handle, flag) == 0 } + } + + pub fn camera_disable_flag(&self, flag: DWORD) -> bool { + unsafe { SimConnect_CameraDisableFlag(self.handle, flag) == 0 } + } + + pub fn subscribe_to_camera_status_update(&self) -> bool { + unsafe { SimConnect_SubscribeToCameraStatusUpdate(self.handle) == 0 } + } + + pub fn unsubscribe_to_camera_status_update(&self) -> bool { + unsafe { SimConnect_UnsubscribeToCameraStatusUpdate(self.handle) == 0 } + } + + pub fn enumerate_camera_definitions(&self) -> bool { + unsafe { SimConnect_EnumerateCameraDefinitions(self.handle) == 0 } + } + + pub fn camera_set_using_camera_definition(&self, camera_definition: &str) -> bool { + let def = cstring(camera_definition); + unsafe { SimConnect_CameraSetUsingCameraDefinition(self.handle, def.as_ptr()) == 0 } + } + + pub fn subscribe_to_camera_world_locker_status_update(&self) -> bool { + unsafe { SimConnect_SubscribeToCameraWorldLockerStatusUpdate(self.handle) == 0 } + } + + pub fn unsubscribe_to_camera_world_locker_status_update(&self) -> bool { + unsafe { SimConnect_UnsubscribeToCameraWorldLockerStatusUpdate(self.handle) == 0 } + } + + pub unsafe fn request_camera_world_locker( + &self, + locker_position: SIMCONNECT_DATA_XYZ, + referential: SIMCONNECT_POSITION_REFERENTIAL, + object_id: DWORD, + ) -> bool { + unsafe { + SimConnect_RequestCameraWorldLocker(self.handle, locker_position, referential, object_id) == 0 + } + } + + pub fn delete_camera_world_locker(&self) -> bool { + unsafe { SimConnect_DeleteCameraWorldLocker(self.handle) == 0 } + } + + // ==================== CommBus ==================== + + pub fn subscribe_to_comm_bus_event(&self, event_id: SIMCONNECT_CLIENT_EVENT_ID, event_name: &str) -> bool { + let name = cstring(event_name); + unsafe { SimConnect_SubscribeToCommBusEvent(self.handle, event_id, name.as_ptr()) == 0 } + } + + pub fn unsubscribe_to_comm_bus_event(&self, event_id: SIMCONNECT_CLIENT_EVENT_ID) -> bool { + unsafe { SimConnect_UnsubscribeToCommBusEvent(self.handle, event_id) == 0 } + } + + pub unsafe fn call_comm_bus_event( + &self, + event_name: &str, + broadcast_to: SIMCONNECT_COMM_BUS_BROADCAST_TO, + buffer_size: DWORD, + data: *const std::os::raw::c_char, + ) -> bool { + let name = cstring(event_name); + unsafe { + SimConnect_CallCommBusEvent( + self.handle, + name.as_ptr(), + broadcast_to, + buffer_size, + data, + ) == 0 + } + } + + // ==================== Flow Events ==================== + + pub fn subscribe_to_flow_event(&self) -> bool { + unsafe { SimConnect_SubscribeToFlowEvent(self.handle) == 0 } + } + + pub fn unsubscribe_to_flow_event(&self) -> bool { + unsafe { SimConnect_UnsubscribeToFlowEvent(self.handle) == 0 } + } + + // ==================== Menu ==================== + + pub fn menu_add_item( + &self, + menu_item: &str, + event_id: SIMCONNECT_CLIENT_EVENT_ID, + data: DWORD, + ) -> bool { + let item = cstring(menu_item); + unsafe { SimConnect_MenuAddItem(self.handle, item.as_ptr(), event_id, data) == 0 } + } + + pub fn menu_add_sub_item( + &self, + menu_event_id: SIMCONNECT_CLIENT_EVENT_ID, + menu_item: &str, + sub_menu_event_id: SIMCONNECT_CLIENT_EVENT_ID, + data: DWORD, + ) -> bool { + let item = cstring(menu_item); + unsafe { + SimConnect_MenuAddSubItem(self.handle, menu_event_id, item.as_ptr(), sub_menu_event_id, data) == 0 + } + } + + pub fn menu_delete_item(&self, event_id: SIMCONNECT_CLIENT_EVENT_ID) -> bool { + unsafe { SimConnect_MenuDeleteItem(self.handle, event_id) == 0 } + } + + pub fn menu_delete_sub_item( + &self, + event_id: SIMCONNECT_CLIENT_EVENT_ID, + sub_event_id: SIMCONNECT_CLIENT_EVENT_ID, + ) -> bool { + unsafe { SimConnect_MenuDeleteSubItem(self.handle, event_id, sub_event_id) == 0 } + } + + // ==================== Other ==================== + + pub fn enumerate_controllers(&self) -> bool { + unsafe { SimConnect_EnumerateControllers(self.handle) == 0 } + } + + pub fn enumerate_sim_objects_and_liveries( + &self, + request_id: SIMCONNECT_DATA_REQUEST_ID, + object_type: SIMCONNECT_SIMOBJECT_TYPE, + ) -> bool { + unsafe { + SimConnect_EnumerateSimObjectsAndLiveries(self.handle, request_id, object_type) == 0 + } + } + + pub fn enumerate_input_events(&self, request_id: SIMCONNECT_DATA_REQUEST_ID) -> bool { + unsafe { SimConnect_EnumerateInputEvents(self.handle, request_id) == 0 } + } + + pub fn get_input_event(&self, request_id: SIMCONNECT_DATA_REQUEST_ID, hash: u64) -> bool { + unsafe { SimConnect_GetInputEvent(self.handle, request_id, hash) == 0 } + } + + pub unsafe fn set_input_event( + &self, + hash: u64, + unit_size: DWORD, + value: *mut std::os::raw::c_void, + ) -> bool { + unsafe { SimConnect_SetInputEvent(self.handle, hash, unit_size, value) == 0 } + } + + pub fn subscribe_input_event(&self, hash: u64) -> bool { + unsafe { SimConnect_SubscribeInputEvent(self.handle, hash) == 0 } + } + + pub fn unsubscribe_input_event(&self, hash: u64) -> bool { + unsafe { SimConnect_UnsubscribeInputEvent(self.handle, hash) == 0 } + } + + pub fn enumerate_input_event_params(&self, hash: u64) -> bool { + unsafe { SimConnect_EnumerateInputEventParams(self.handle, hash) == 0 } + } + + pub unsafe fn execute_action( + &self, + request_id: DWORD, + action_id: &str, + unit_size: DWORD, + param_values: *mut std::os::raw::c_void, + ) -> bool { + let action = cstring(action_id); + unsafe { + SimConnect_ExecuteAction(self.handle, request_id, action.as_ptr(), unit_size, param_values) == 0 + } + } + + pub unsafe fn text( + &self, + text_type: SIMCONNECT_TEXT_TYPE, + time_in_seconds: f32, + event_id: SIMCONNECT_CLIENT_EVENT_ID, + unit_size: DWORD, + data_set: *mut std::os::raw::c_void, + ) -> bool { + unsafe { + SimConnect_Text(self.handle, text_type, time_in_seconds, event_id, unit_size, data_set) == 0 + } + } + + pub unsafe fn get_last_sent_packet_id(&self, error: *mut DWORD) -> bool { + unsafe { SimConnect_GetLastSentPacketID(self.handle, error) == 0 } + } + + pub unsafe fn call_dispatch( + &self, + dispatch_callback: DispatchProc, + context: *mut std::os::raw::c_void, + ) -> bool { + unsafe { SimConnect_CallDispatch(self.handle, dispatch_callback, context) == 0 } + } + + pub unsafe fn request_response_times(&self, count: DWORD, elapsed_seconds: *mut f32) -> bool { + unsafe { SimConnect_RequestResponseTimes(self.handle, count, elapsed_seconds) == 0 } + } + + // ==================== String Utilities ==================== + + pub unsafe fn retrieve_string( + p_data: *mut SIMCONNECT_RECV, + cb_data: DWORD, + p_string_v: *mut std::os::raw::c_void, + psz_string: *mut *mut std::os::raw::c_char, + pcb_string: *mut DWORD, + ) -> bool { + unsafe { + SimConnect_RetrieveString(p_data, cb_data, p_string_v, psz_string, pcb_string) == 0 + } + } + + pub unsafe fn insert_string( + p_dest: *mut std::os::raw::c_char, + cb_dest: DWORD, + pp_end: *mut *mut std::os::raw::c_void, + pcb_string: *mut DWORD, + p_source: *const std::os::raw::c_char, + ) -> bool { + unsafe { + SimConnect_InsertString(p_dest, cb_dest, pp_end, pcb_string, p_source) == 0 + } + } + + // ==================== Main Message Loop ==================== + + pub fn get_next_message(&self) -> Result, &str> { + unsafe { + let mut data_buf: *mut SIMCONNECT_RECV = ptr::null_mut(); + let mut size_buf: DWORD = 0; + + if SimConnect_GetNextDispatch(self.handle, &mut data_buf, &mut size_buf) != 0 { + return Err("Failed getting data from SimConnect"); + } + + if data_buf.is_null() { + return Ok(DispatchResult::Null); + } + + match (*data_buf).dwID as SIMCONNECT_RECV_ID { + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_NULL => Ok(DispatchResult::Null), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EXCEPTION => Ok(DispatchResult::Exception(&*(data_buf as *const SIMCONNECT_RECV_EXCEPTION))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_OPEN => Ok(DispatchResult::Open(&*(data_buf as *const SIMCONNECT_RECV_OPEN))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_QUIT => Ok(DispatchResult::Quit(&*(data_buf as *const SIMCONNECT_RECV_QUIT))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT => Ok(DispatchResult::Event(&*(data_buf as *const SIMCONNECT_RECV_EVENT))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_OBJECT_ADDREMOVE => Ok(DispatchResult::EventObjectAddRemove(&*(data_buf as *const SIMCONNECT_RECV_EVENT_OBJECT_ADDREMOVE))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_FILENAME => Ok(DispatchResult::EventFilename(&*(data_buf as *const SIMCONNECT_RECV_EVENT_FILENAME))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_FRAME => Ok(DispatchResult::EventFrame(&*(data_buf as *const SIMCONNECT_RECV_EVENT_FRAME))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_SIMOBJECT_DATA => Ok(DispatchResult::SimObjectData(&*(data_buf as *const SIMCONNECT_RECV_SIMOBJECT_DATA))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_SIMOBJECT_DATA_BYTYPE => Ok(DispatchResult::SimObjectDataByType(&*(data_buf as *const SIMCONNECT_RECV_SIMOBJECT_DATA_BYTYPE))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_WEATHER_OBSERVATION => Ok(DispatchResult::WeatherObservation(&*(data_buf as *const SIMCONNECT_RECV_WEATHER_OBSERVATION))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_CLOUD_STATE => Ok(DispatchResult::CloudState(&*(data_buf as *const SIMCONNECT_RECV_CLOUD_STATE))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_ASSIGNED_OBJECT_ID => Ok(DispatchResult::AssignedObjectId(&*(data_buf as *const SIMCONNECT_RECV_ASSIGNED_OBJECT_ID))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_RESERVED_KEY => Ok(DispatchResult::ReservedKey(&*(data_buf as *const SIMCONNECT_RECV_RESERVED_KEY))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_CUSTOM_ACTION => Ok(DispatchResult::CustomAction(&*(data_buf as *const SIMCONNECT_RECV_CUSTOM_ACTION))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_SYSTEM_STATE => Ok(DispatchResult::SystemState(&*(data_buf as *const SIMCONNECT_RECV_SYSTEM_STATE))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_CLIENT_DATA => Ok(DispatchResult::ClientData(&*(data_buf as *const SIMCONNECT_RECV_CLIENT_DATA))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_WEATHER_MODE => Ok(DispatchResult::EventWeatherMode(&*(data_buf as *const SIMCONNECT_RECV_EVENT_WEATHER_MODE))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_AIRPORT_LIST => Ok(DispatchResult::AirportList(&*(data_buf as *const SIMCONNECT_RECV_AIRPORT_LIST))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_VOR_LIST => Ok(DispatchResult::VorList(&*(data_buf as *const SIMCONNECT_RECV_VOR_LIST))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_NDB_LIST => Ok(DispatchResult::NdbList(&*(data_buf as *const SIMCONNECT_RECV_NDB_LIST))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_WAYPOINT_LIST => Ok(DispatchResult::WaypointList(&*(data_buf as *const SIMCONNECT_RECV_WAYPOINT_LIST))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_MULTIPLAYER_SERVER_STARTED => Ok(DispatchResult::EventMultiplayerServerStarted(&*(data_buf as *const SIMCONNECT_RECV_EVENT_MULTIPLAYER_SERVER_STARTED))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_MULTIPLAYER_CLIENT_STARTED => Ok(DispatchResult::EventMultiplayerClientStarted(&*(data_buf as *const SIMCONNECT_RECV_EVENT_MULTIPLAYER_CLIENT_STARTED))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_MULTIPLAYER_SESSION_ENDED => Ok(DispatchResult::EventMultiplayerSessionEnded(&*(data_buf as *const SIMCONNECT_RECV_EVENT_MULTIPLAYER_SESSION_ENDED))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_RACE_END => Ok(DispatchResult::EventRaceEnd(&*(data_buf as *const SIMCONNECT_RECV_EVENT_RACE_END))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_RACE_LAP => Ok(DispatchResult::EventRaceLap(&*(data_buf as *const SIMCONNECT_RECV_EVENT_RACE_LAP))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_EX1 => Ok(DispatchResult::EventEx1(&*(data_buf as *const SIMCONNECT_RECV_EVENT_EX1))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_FACILITY_DATA => Ok(DispatchResult::FacilityData(&*(data_buf as *const SIMCONNECT_RECV_FACILITY_DATA))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_FACILITY_DATA_END => Ok(DispatchResult::FacilityDataEnd(&*(data_buf as *const SIMCONNECT_RECV_FACILITY_DATA_END))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_FACILITY_MINIMAL_LIST => Ok(DispatchResult::FacilityMinimalList(&*(data_buf as *const SIMCONNECT_RECV_FACILITY_MINIMAL_LIST))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_JETWAY_DATA => Ok(DispatchResult::JetwayData(&*(data_buf as *const SIMCONNECT_RECV_JETWAY_DATA))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_ACTION_CALLBACK => Ok(DispatchResult::ActionCallback(&*(data_buf as *const SIMCONNECT_RECV_ACTION_CALLBACK))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_ENUMERATE_INPUT_EVENTS => Ok(DispatchResult::EnumerateInputEvents(&*(data_buf as *const SIMCONNECT_RECV_ENUMERATE_INPUT_EVENTS))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_GET_INPUT_EVENT => Ok(DispatchResult::GetInputEvent(&*(data_buf as *const SIMCONNECT_RECV_GET_INPUT_EVENT))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_SUBSCRIBE_INPUT_EVENT => Ok(DispatchResult::SubscribeInputEvent(&*(data_buf as *const SIMCONNECT_RECV_SUBSCRIBE_INPUT_EVENT))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_ENUMERATE_INPUT_EVENT_PARAMS => Ok(DispatchResult::EnumerateInputEventParams(&*(data_buf as *const SIMCONNECT_RECV_ENUMERATE_INPUT_EVENT_PARAMS))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_CONTROLLERS_LIST => Ok(DispatchResult::ControllersList(&*(data_buf as *const SIMCONNECT_RECV_CONTROLLERS_LIST))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_ENUMERATE_SIMOBJECT_AND_LIVERY_LIST => Ok(DispatchResult::EnumerateSimObjectAndLiveryList(&*(data_buf as *const SIMCONNECT_RECV_ENUMERATE_SIMOBJECT_AND_LIVERY_LIST))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_FLOW_EVENT => Ok(DispatchResult::FlowEvent(&*(data_buf as *const SIMCONNECT_RECV_FLOW_EVENT))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_CAMERA_DATA => Ok(DispatchResult::CameraData(&*(data_buf as *const SIMCONNECT_RECV_CAMERA_DATA))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_CAMERA_STATUS => Ok(DispatchResult::CameraStatus(&*(data_buf as *const SIMCONNECT_RECV_CAMERA_STATUS))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_CAMERA_DEFINITION_LIST => Ok(DispatchResult::CameraDefinitionList(&*(data_buf as *const SIMCONNECT_RECV_CAMERA_DEFINITION_LIST))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_COMM_BUS => Ok(DispatchResult::CommBus(&*(data_buf as *const SIMCONNECT_RECV_COMM_BUS))), + SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_CAMERA_WORLD_LOCKER => Ok(DispatchResult::CameraWorldLocker(&*(data_buf as *const SIMCONNECT_RECV_CAMERA_WORLD_LOCKER))), + _ => Err("Unhandled RECV_ID"), + } + } + } +} + +impl Drop for SimConnector { + fn drop(&mut self) { + if !self.handle.is_null() { + let _ = self.close(); + } + } +} + +#[inline] +fn cstring(s: &str) -> CString { + CString::new(s).expect("string contained interior nul byte") +} diff --git a/src/lib.rs b/src/lib.rs index 9a47fe7..951d241 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,1206 +1,5 @@ -#![allow(clippy::too_many_arguments, clippy::missing_safety_doc)] -#![allow(non_upper_case_globals)] -#![allow(non_camel_case_types)] -#![allow(non_snake_case)] +#[cfg(feature = "fs2020")] +pub use simconnect_fs2020 as fs2020; -use std::ffi::CString; -use std::mem::transmute_copy; -use std::ptr; - -include!(concat!(env!("OUT_DIR"), "/bindings.rs")); - -/// Enumerations for all the possible data types received from SimConnect -#[derive(Debug)] -pub enum DispatchResult<'a> { - Null, - Exception(&'a SIMCONNECT_RECV_EXCEPTION), - Open(&'a SIMCONNECT_RECV_OPEN), - Quit(&'a SIMCONNECT_RECV_QUIT), - Event(&'a SIMCONNECT_RECV_EVENT), - EventObjectAddRemove(&'a SIMCONNECT_RECV_EVENT_OBJECT_ADDREMOVE), - EventFilename(&'a SIMCONNECT_RECV_EVENT_FILENAME), - EventFrame(&'a SIMCONNECT_RECV_EVENT_FRAME), - SimObjectData(&'a SIMCONNECT_RECV_SIMOBJECT_DATA), - SimObjectDataByType(&'a SIMCONNECT_RECV_SIMOBJECT_DATA_BYTYPE), - WeatherObservation(&'a SIMCONNECT_RECV_WEATHER_OBSERVATION), - CloudState(&'a SIMCONNECT_RECV_CLOUD_STATE), - AssignedObjectId(&'a SIMCONNECT_RECV_ASSIGNED_OBJECT_ID), - ReservedKey(&'a SIMCONNECT_RECV_RESERVED_KEY), - CustomAction(&'a SIMCONNECT_RECV_CUSTOM_ACTION), - SystemState(&'a SIMCONNECT_RECV_SYSTEM_STATE), - ClientData(&'a SIMCONNECT_RECV_CLIENT_DATA), - EventWeatherMode(&'a SIMCONNECT_RECV_EVENT_WEATHER_MODE), - AirportList(&'a SIMCONNECT_RECV_AIRPORT_LIST), - VorList(&'a SIMCONNECT_RECV_VOR_LIST), - NdbList(&'a SIMCONNECT_RECV_NDB_LIST), - WaypointList(&'a SIMCONNECT_RECV_WAYPOINT_LIST), - EventMultiplayerServerStarted(&'a SIMCONNECT_RECV_EVENT_MULTIPLAYER_SERVER_STARTED), - EventMultiplayerClientStarted(&'a SIMCONNECT_RECV_EVENT_MULTIPLAYER_CLIENT_STARTED), - EventMultiplayerSessionEnded(&'a SIMCONNECT_RECV_EVENT_MULTIPLAYER_SESSION_ENDED), - EventRaceEnd(&'a SIMCONNECT_RECV_EVENT_RACE_END), - EventRaceLap(&'a SIMCONNECT_RECV_EVENT_RACE_LAP), - EventEx1(&'a SIMCONNECT_RECV_EVENT_EX1), - FacilityData(&'a SIMCONNECT_RECV_FACILITY_DATA), - FacilityDataEnd(&'a SIMCONNECT_RECV_FACILITY_DATA_END), - FacilityMinimalList(&'a SIMCONNECT_RECV_FACILITY_MINIMAL_LIST), - JetwayData(&'a SIMCONNECT_RECV_JETWAY_DATA), - ActionCallback(&'a SIMCONNECT_RECV_ACTION_CALLBACK), - EnumerateInputEvents(&'a SIMCONNECT_RECV_ENUMERATE_INPUT_EVENTS), - GetInputEvent(&'a SIMCONNECT_RECV_GET_INPUT_EVENT), - SubscribeInputEvent(&'a SIMCONNECT_RECV_SUBSCRIBE_INPUT_EVENT), - EnumerateInputEventParams(&'a SIMCONNECT_RECV_ENUMERATE_INPUT_EVENT_PARAMS), - ControllersList(&'a SIMCONNECT_RECV_CONTROLLERS_LIST), -} - -/// Handles communication between the client program and SimConnect -#[derive(Debug)] -pub struct SimConnector { - sim_connect_handle: HANDLE, -} - -impl Default for SimConnector { - fn default() -> Self { - Self { - sim_connect_handle: std::ptr::null_mut(), - } - } -} - -impl SimConnector { - pub fn new() -> Self { - Self::default() - } - - pub fn connect(&mut self, program_name: &str) -> bool { - unsafe { - let temp_1 = ptr::null_mut(); - let temp_2 = ptr::null_mut(); - - let program_name = CString::new(program_name).unwrap(); - - SimConnect_Open( - &mut self.sim_connect_handle, - program_name.as_ptr(), - temp_1, - 0, - temp_2, - 0, - ); - - !self.sim_connect_handle.is_null() - } - } - - pub fn add_data_definition( - &self, - define_id: SIMCONNECT_DATA_DEFINITION_ID, - datum_name: &str, - units_name: &str, - datum_type: SIMCONNECT_DATATYPE, - datum_id: DWORD, - epsilon: f32, - ) -> bool { - let datum_name = CString::new(datum_name).unwrap(); - let units_name = CString::new(units_name).unwrap(); - - unsafe { - SimConnect_AddToDataDefinition( - self.sim_connect_handle, - define_id, - datum_name.as_ptr(), - units_name.as_ptr(), - datum_type, - epsilon, - datum_id, - ) == 0 - } - } - - pub fn set_system_event_state( - &self, - event_id: SIMCONNECT_CLIENT_EVENT_ID, - state: SIMCONNECT_STATE, - ) -> bool { - unsafe { SimConnect_SetSystemEventState(self.sim_connect_handle, event_id, state) == 0 } - } - - pub fn remove_client_event( - &self, - group_id: SIMCONNECT_NOTIFICATION_GROUP_ID, - event_id: SIMCONNECT_CLIENT_EVENT_ID, - ) -> bool { - unsafe { SimConnect_RemoveClientEvent(self.sim_connect_handle, group_id, event_id) == 0 } - } - - pub fn clear_notification_group(&self, group_id: SIMCONNECT_NOTIFICATION_GROUP_ID) -> bool { - unsafe { SimConnect_ClearNotificationGroup(self.sim_connect_handle, group_id) == 0 } - } - - pub fn request_notification_group( - &self, - group_id: SIMCONNECT_NOTIFICATION_GROUP_ID, - reserved: DWORD, - flags: DWORD, - ) -> bool { - unsafe { - SimConnect_RequestNotificationGroup(self.sim_connect_handle, group_id, reserved, flags) - == 0 - } - } - - pub fn clear_data_definition(&self, define_id: SIMCONNECT_DATA_DEFINITION_ID) -> bool { - unsafe { SimConnect_ClearDataDefinition(self.sim_connect_handle, define_id) == 0 } - } - - pub fn create_client_data( - &self, - data_id: SIMCONNECT_CLIENT_DATA_ID, - size: DWORD, - flags: SIMCONNECT_CREATE_CLIENT_DATA_FLAG, - ) -> bool { - unsafe { SimConnect_CreateClientData(self.sim_connect_handle, data_id, size, flags) == 0 } - } - - pub fn request_data_on_sim_object_type( - &self, - request_id: SIMCONNECT_DATA_REQUEST_ID, - define_id: SIMCONNECT_DATA_DEFINITION_ID, - radius_in_meters: DWORD, - object_type: SIMCONNECT_SIMOBJECT_TYPE, - ) -> bool { - unsafe { - SimConnect_RequestDataOnSimObjectType( - self.sim_connect_handle, - request_id, - define_id, - radius_in_meters, - object_type, - ) == 0 - } - } - - pub fn remove_input_event( - &self, - group_id: SIMCONNECT_INPUT_GROUP_ID, - input_definition: &str, - ) -> bool { - let input_definition = CString::new(input_definition).unwrap(); - - unsafe { - SimConnect_RemoveInputEvent( - self.sim_connect_handle, - group_id, - input_definition.as_ptr(), - ) == 0 - } - } - - pub fn clear_input_group(&self, group_id: SIMCONNECT_INPUT_GROUP_ID) -> bool { - unsafe { SimConnect_ClearInputGroup(self.sim_connect_handle, group_id) == 0 } - } - - pub fn request_reserved_key( - &self, - event_id: SIMCONNECT_CLIENT_EVENT_ID, - key_choice_1: &str, - key_choice_2: &str, - key_choice_3: &str, - ) -> bool { - let key_choice_1 = CString::new(key_choice_1).unwrap(); - let key_choice_2 = CString::new(key_choice_2).unwrap(); - let key_choice_3 = CString::new(key_choice_3).unwrap(); - - unsafe { - SimConnect_RequestReservedKey( - self.sim_connect_handle, - event_id, - key_choice_1.as_ptr(), - key_choice_2.as_ptr(), - key_choice_3.as_ptr(), - ) == 0 - } - } - - pub fn unsubscribe_from_system_event(&self, event_id: SIMCONNECT_CLIENT_EVENT_ID) -> bool { - unsafe { SimConnect_UnsubscribeFromSystemEvent(self.sim_connect_handle, event_id) == 0 } - } - - pub fn ai_create_parked_atc_aircraft( - &self, - container_title: &str, - tail_number: &str, - airport_id: &str, - request_id: SIMCONNECT_DATA_REQUEST_ID, - ) -> bool { - let container_title = CString::new(container_title).unwrap(); - let tail_number = CString::new(tail_number).unwrap(); - let airport_id = CString::new(airport_id).unwrap(); - - unsafe { - SimConnect_AICreateParkedATCAircraft( - self.sim_connect_handle, - container_title.as_ptr(), - tail_number.as_ptr(), - airport_id.as_ptr(), - request_id, - ) == 0 - } - } - - pub fn ai_create_enroute_atc_aircraft( - &self, - container_title: &str, - tail_number: &str, - flight_number: i32, - flight_plan_path: &str, - flight_plan_position: f64, - touch_and_go: bool, - request_id: SIMCONNECT_DATA_REQUEST_ID, - ) -> bool { - let container_title = CString::new(container_title).unwrap(); - let tail_number = CString::new(tail_number).unwrap(); - let flight_plan_path = CString::new(flight_plan_path).unwrap(); - - unsafe { - SimConnect_AICreateEnrouteATCAircraft( - self.sim_connect_handle, - container_title.as_ptr(), - tail_number.as_ptr(), - flight_number, - flight_plan_path.as_ptr(), - flight_plan_position, - touch_and_go as i32, - request_id, - ) == 0 - } - } - - pub fn ai_create_non_atc_aircraft( - &self, - container_title: &str, - tail_number: &str, - init_pos: SIMCONNECT_DATA_INITPOSITION, - request_id: SIMCONNECT_DATA_REQUEST_ID, - ) -> bool { - let container_title = CString::new(container_title).unwrap(); - let tail_number = CString::new(tail_number).unwrap(); - - unsafe { - SimConnect_AICreateNonATCAircraft( - self.sim_connect_handle, - container_title.as_ptr(), - tail_number.as_ptr(), - init_pos, - request_id, - ) == 0 - } - } - - pub fn ai_create_simulated_object( - &self, - container_title: &str, - init_pos: SIMCONNECT_DATA_INITPOSITION, - request_id: SIMCONNECT_DATA_REQUEST_ID, - ) -> bool { - let container_title = CString::new(container_title).unwrap(); - - unsafe { - SimConnect_AICreateSimulatedObject( - self.sim_connect_handle, - container_title.as_ptr(), - init_pos, - request_id, - ) == 0 - } - } - - pub fn ai_release_control( - &self, - object_id: SIMCONNECT_OBJECT_ID, - request_id: SIMCONNECT_DATA_REQUEST_ID, - ) -> bool { - unsafe { SimConnect_AIReleaseControl(self.sim_connect_handle, object_id, request_id) == 0 } - } - - pub fn ai_remove_object( - &self, - object_id: SIMCONNECT_OBJECT_ID, - request_id: SIMCONNECT_DATA_REQUEST_ID, - ) -> bool { - unsafe { SimConnect_AIRemoveObject(self.sim_connect_handle, object_id, request_id) == 0 } - } - - pub fn ai_set_aircraft_flight_plan( - &self, - object_id: SIMCONNECT_OBJECT_ID, - flight_plan_path: &str, - request_id: SIMCONNECT_DATA_REQUEST_ID, - ) -> bool { - let flight_plan_path = CString::new(flight_plan_path).unwrap(); - - unsafe { - SimConnect_AISetAircraftFlightPlan( - self.sim_connect_handle, - object_id, - flight_plan_path.as_ptr(), - request_id, - ) == 0 - } - } - - pub fn execute_mission_action(&self, instance_id: GUID) -> bool { - unsafe { SimConnect_ExecuteMissionAction(self.sim_connect_handle, instance_id) == 0 } - } - - pub fn complete_custom_mission_action(&self, instance_id: GUID) -> bool { - unsafe { SimConnect_CompleteCustomMissionAction(self.sim_connect_handle, instance_id) == 0 } - } - - pub fn close(&self) -> bool { - unsafe { SimConnect_Close(self.sim_connect_handle) == 0 } - } - - pub unsafe fn get_last_sent_packet_id(&self, error: *mut DWORD) -> bool { - unsafe { SimConnect_GetLastSentPacketID(self.sim_connect_handle, error) == 0 } - } - - pub unsafe fn call_dispatch( - &self, - dispatch_callback: DispatchProc, - context: *mut std::os::raw::c_void, - ) -> bool { - unsafe { SimConnect_CallDispatch(self.sim_connect_handle, dispatch_callback, context) == 0 } - } - - pub unsafe fn request_response_times(&self, count: DWORD, elapsed_seconds: *mut f32) -> bool { - unsafe { - SimConnect_RequestResponseTimes(self.sim_connect_handle, count, elapsed_seconds) == 0 - } - } - - pub fn camera_set_relative_6dof( - &self, - delta_x: f32, - delta_y: f32, - delta_z: f32, - pitch: f32, - bank: f32, - heading: f32, - ) -> bool { - unsafe { - SimConnect_CameraSetRelative6DOF( - self.sim_connect_handle, - delta_x, - delta_y, - delta_z, - pitch, - bank, - heading, - ) == 0 - } - } - - pub fn menu_add_item( - &self, - menu_item: &str, - event_id: SIMCONNECT_CLIENT_EVENT_ID, - data: DWORD, - ) -> bool { - let menu_item = CString::new(menu_item).unwrap(); - - unsafe { - SimConnect_MenuAddItem(self.sim_connect_handle, menu_item.as_ptr(), event_id, data) == 0 - } - } - - pub fn menu_delete_item(&self, event_id: SIMCONNECT_CLIENT_EVENT_ID) -> bool { - unsafe { SimConnect_MenuDeleteItem(self.sim_connect_handle, event_id) == 0 } - } - - pub fn menu_delete_sub_item( - &self, - event_id: SIMCONNECT_CLIENT_EVENT_ID, - sub_event_id: SIMCONNECT_CLIENT_EVENT_ID, - ) -> bool { - unsafe { - SimConnect_MenuDeleteSubItem(self.sim_connect_handle, event_id, sub_event_id) == 0 - } - } - - pub fn request_system_state( - &self, - request_id: SIMCONNECT_DATA_REQUEST_ID, - state: &str, - ) -> bool { - let state = CString::new(state).unwrap(); - - unsafe { - SimConnect_RequestSystemState(self.sim_connect_handle, request_id, state.as_ptr()) == 0 - } - } - - pub fn map_client_data_name_to_id( - &self, - client_data_name: &str, - data_id: SIMCONNECT_CLIENT_DATA_ID, - ) -> bool { - let client_data_name = CString::new(client_data_name).unwrap(); - - unsafe { - SimConnect_MapClientDataNameToID( - self.sim_connect_handle, - client_data_name.as_ptr(), - data_id, - ) == 0 - } - } - - pub fn add_to_client_data_definition( - &self, - define_id: SIMCONNECT_DATA_DEFINITION_ID, - offset: DWORD, - size_or_type: DWORD, - epsilon: f32, - datum_id: DWORD, - ) -> bool { - unsafe { - SimConnect_AddToClientDataDefinition( - self.sim_connect_handle, - define_id, - offset, - size_or_type, - epsilon, - datum_id, - ) == 0 - } - } - - pub fn clear_client_data_definition(&self, define_id: SIMCONNECT_DATA_DEFINITION_ID) -> bool { - unsafe { SimConnect_ClearClientDataDefinition(self.sim_connect_handle, define_id) == 0 } - } - - pub fn request_client_data( - &self, - data_id: SIMCONNECT_CLIENT_DATA_ID, - request_id: SIMCONNECT_DATA_REQUEST_ID, - define_id: SIMCONNECT_DATA_DEFINITION_ID, - period: SIMCONNECT_CLIENT_DATA_PERIOD, - flags: SIMCONNECT_CLIENT_DATA_REQUEST_FLAG, - origin: DWORD, - interval: DWORD, - limit: DWORD, - ) -> bool { - unsafe { - SimConnect_RequestClientData( - self.sim_connect_handle, - data_id, - request_id, - define_id, - period, - flags, - origin, - interval, - limit, - ) == 0 - } - } - - pub unsafe fn set_client_data( - &self, - data_id: SIMCONNECT_CLIENT_DATA_ID, - define_id: SIMCONNECT_DATA_DEFINITION_ID, - flags: DWORD, - reserved: DWORD, - unit_size: DWORD, - data_set: *mut std::os::raw::c_void, - ) -> bool { - unsafe { - SimConnect_SetClientData( - self.sim_connect_handle, - data_id, - define_id, - flags, - reserved, - unit_size, - data_set, - ) == 0 - } - } - - pub fn flight_load(&self, file_name: &str) -> bool { - let file_name = CString::new(file_name).unwrap(); - - unsafe { SimConnect_FlightLoad(self.sim_connect_handle, file_name.as_ptr()) == 0 } - } - - pub unsafe fn text( - &self, - text_type: SIMCONNECT_TEXT_TYPE, - time_in_seconds: f32, - event_id: SIMCONNECT_CLIENT_EVENT_ID, - unit_size: DWORD, - data_set: *mut std::os::raw::c_void, - ) -> bool { - unsafe { - SimConnect_Text( - self.sim_connect_handle, - text_type, - time_in_seconds, - event_id, - unit_size, - data_set, - ) == 0 - } - } - - pub fn subscribe_to_facilities( - &self, - list_type: SIMCONNECT_FACILITY_LIST_TYPE, - request_id: SIMCONNECT_DATA_REQUEST_ID, - ) -> bool { - unsafe { - SimConnect_SubscribeToFacilities(self.sim_connect_handle, list_type, request_id) == 0 - } - } - - pub fn unsubscribe_to_facilities(&self, list_type: SIMCONNECT_FACILITY_LIST_TYPE) -> bool { - unsafe { SimConnect_UnsubscribeToFacilities(self.sim_connect_handle, list_type) == 0 } - } - - pub fn request_facilities_list( - &self, - list_type: SIMCONNECT_FACILITY_LIST_TYPE, - request_id: SIMCONNECT_DATA_REQUEST_ID, - ) -> bool { - unsafe { - SimConnect_RequestFacilitiesList(self.sim_connect_handle, list_type, request_id) == 0 - } - } - - pub fn request_data_on_sim_object( - &self, - request_id: SIMCONNECT_DATA_REQUEST_ID, - define_id: SIMCONNECT_DATA_DEFINITION_ID, - object_id: SIMCONNECT_OBJECT_ID, - period: SIMCONNECT_CLIENT_DATA_PERIOD, - flags: SIMCONNECT_DATA_REQUEST_FLAG, - origin: DWORD, - interval: DWORD, - limit: DWORD, - ) -> bool { - unsafe { - SimConnect_RequestDataOnSimObject( - self.sim_connect_handle, - request_id, - define_id, - object_id, - period, - flags, - origin, - interval, - limit, - ) == 0 - } - } - - pub unsafe fn set_data_on_sim_object( - &self, - define_id: SIMCONNECT_DATA_DEFINITION_ID, - object_id: SIMCONNECT_OBJECT_ID, - flags: SIMCONNECT_DATA_SET_FLAG, - array_count: DWORD, - size: DWORD, - pntr: *mut ::std::os::raw::c_void, - ) -> bool { - unsafe { - SimConnect_SetDataOnSimObject( - self.sim_connect_handle, - define_id, - object_id, - flags, - array_count, - size, - pntr, - ) == 0 - } - } - - pub fn subscribe_to_system_event( - &self, - event_id: SIMCONNECT_CLIENT_EVENT_ID, - event_name: &str, - ) -> bool { - let event_name = CString::new(event_name).unwrap(); - - unsafe { - SimConnect_SubscribeToSystemEvent( - self.sim_connect_handle, - event_id, - event_name.as_ptr(), - ) == 0 - } - } - - pub fn map_client_event_to_sim_event( - &self, - event_id: SIMCONNECT_CLIENT_EVENT_ID, - event_name: &str, - ) -> bool { - let event_name = CString::new(event_name).unwrap(); - - unsafe { - SimConnect_MapClientEventToSimEvent( - self.sim_connect_handle, - event_id, - event_name.as_ptr(), - ) == 0 - } - } - - pub fn transmit_client_event( - &self, - object_id: SIMCONNECT_OBJECT_ID, - event_id: SIMCONNECT_CLIENT_EVENT_ID, - dw_data: DWORD, - group_id: SIMCONNECT_NOTIFICATION_GROUP_ID, - flags: SIMCONNECT_EVENT_FLAG, - ) -> bool { - unsafe { - SimConnect_TransmitClientEvent( - self.sim_connect_handle, - object_id, - event_id, - dw_data, - group_id, - flags, - ) == 0 - } - } - - pub fn add_client_event_to_notification_group( - &self, - group_id: SIMCONNECT_NOTIFICATION_GROUP_ID, - event_id: SIMCONNECT_CLIENT_EVENT_ID, - maskable: bool, - ) -> bool { - unsafe { - SimConnect_AddClientEventToNotificationGroup( - self.sim_connect_handle, - group_id, - event_id, - maskable as i32, - ) == 0 - } - } - - pub fn set_notification_group_priority( - &self, - group_id: SIMCONNECT_NOTIFICATION_GROUP_ID, - priority: DWORD, - ) -> bool { - unsafe { - SimConnect_SetNotificationGroupPriority(self.sim_connect_handle, group_id, priority) - == 0 - } - } - - pub fn map_input_event_to_client_event( - &self, - group_id: SIMCONNECT_INPUT_GROUP_ID, - input_definition: &str, - down_event: SIMCONNECT_CLIENT_EVENT_ID, - down_return_value: DWORD, - up_event: SIMCONNECT_CLIENT_EVENT_ID, - up_return_value: DWORD, - maskable: bool, - ) -> bool { - let input_definition = CString::new(input_definition).unwrap(); - - unsafe { - SimConnect_MapInputEventToClientEvent( - self.sim_connect_handle, - group_id, - input_definition.as_ptr(), - down_event, - down_return_value, - up_event, - up_return_value, - maskable as i32, - ) == 0 - } - } - - pub fn set_input_group_state(&self, group_id: SIMCONNECT_INPUT_GROUP_ID, state: DWORD) -> bool { - unsafe { SimConnect_SetInputGroupState(self.sim_connect_handle, group_id, state) == 0 } - } - - pub fn set_input_priority(&self, group_id: SIMCONNECT_INPUT_GROUP_ID, priority: DWORD) -> bool { - unsafe { - SimConnect_SetInputGroupPriority(self.sim_connect_handle, group_id, priority) == 0 - } - } - - pub fn transmit_client_event_ex1( - &self, - object_id: SIMCONNECT_OBJECT_ID, - event_id: SIMCONNECT_CLIENT_EVENT_ID, - group_id: SIMCONNECT_NOTIFICATION_GROUP_ID, - flags: SIMCONNECT_EVENT_FLAG, - data0: DWORD, - data1: DWORD, - data2: DWORD, - data3: DWORD, - data4: DWORD, - ) -> bool { - unsafe { - SimConnect_TransmitClientEvent_EX1( - self.sim_connect_handle, - object_id, - event_id, - group_id, - flags, - data0, - data1, - data2, - data3, - data4, - ) == 0 - } - } - - pub fn add_to_facility_definition( - &self, - define_id: SIMCONNECT_DATA_DEFINITION_ID, - field_name: &str, - ) -> bool { - let field_name = CString::new(field_name).unwrap(); - unsafe { - SimConnect_AddToFacilityDefinition( - self.sim_connect_handle, - define_id, - field_name.as_ptr(), - ) == 0 - } - } - - pub fn request_facility_data( - &self, - define_id: SIMCONNECT_DATA_DEFINITION_ID, - request_id: SIMCONNECT_DATA_REQUEST_ID, - icao: &str, - region: Option<&str>, - ) -> bool { - let icao = CString::new(icao).unwrap(); - let region = region.map(|s| CString::new(s).unwrap()); - - unsafe { - SimConnect_RequestFacilityData( - self.sim_connect_handle, - define_id, - request_id, - icao.as_ptr(), - region.as_ref().map_or(ptr::null(), |s| s.as_ptr()), - ) == 0 - } - } - - pub fn subscribe_to_facilities_ex1( - &self, - list_type: SIMCONNECT_FACILITY_LIST_TYPE, - new_in_range_request_id: SIMCONNECT_DATA_REQUEST_ID, - old_out_of_range_request_id: SIMCONNECT_DATA_REQUEST_ID, - ) -> bool { - unsafe { - SimConnect_SubscribeToFacilities_EX1( - self.sim_connect_handle, - list_type, - new_in_range_request_id, - old_out_of_range_request_id, - ) == 0 - } - } - - pub fn unsubscribe_to_facilities_ex1( - &self, - list_type: SIMCONNECT_FACILITY_LIST_TYPE, - unsubscribe_new_in_range: bool, - unsubscribe_old_out_of_range: bool, - ) -> bool { - unsafe { - SimConnect_UnsubscribeToFacilities_EX1( - self.sim_connect_handle, - list_type, - unsubscribe_new_in_range, - unsubscribe_old_out_of_range, - ) == 0 - } - } - - pub fn request_facilities_list_ex1( - &self, - list_type: SIMCONNECT_FACILITY_LIST_TYPE, - request_id: SIMCONNECT_DATA_REQUEST_ID, - ) -> bool { - unsafe { - SimConnect_RequestFacilitiesList_EX1(self.sim_connect_handle, list_type, request_id) - == 0 - } - } - - pub fn request_facility_data_ex1( - &self, - define_id: SIMCONNECT_DATA_DEFINITION_ID, - request_id: SIMCONNECT_DATA_REQUEST_ID, - icao: &str, - region: Option<&str>, - type_: Option, - ) -> bool { - let icao = CString::new(icao).unwrap(); - let region = region.map(|s| CString::new(s).unwrap()); - - unsafe { - SimConnect_RequestFacilityData_EX1( - self.sim_connect_handle, - define_id, - request_id, - icao.as_ptr(), - region.as_ref().map_or(ptr::null(), |s| s.as_ptr()), - type_.unwrap_or(0) as ::std::os::raw::c_char, - ) == 0 - } - } - - pub unsafe fn request_jetway_data( - &self, - airport_icao: &str, - array_count: DWORD, - indexes: *mut i32, - ) -> bool { - let airport_icao = CString::new(airport_icao).unwrap(); - unsafe { - SimConnect_RequestJetwayData( - self.sim_connect_handle, - airport_icao.as_ptr(), - array_count, - indexes, - ) == 0 - } - } - - pub fn enumerate_controllers(&self) -> bool { - unsafe { SimConnect_EnumerateControllers(self.sim_connect_handle) == 0 } - } - - pub fn map_input_event_to_client_event_ex1( - &self, - group_id: SIMCONNECT_INPUT_GROUP_ID, - input_definition: &str, - down_event: SIMCONNECT_CLIENT_EVENT_ID, - down_return_value: DWORD, - up_event: SIMCONNECT_CLIENT_EVENT_ID, - up_return_value: DWORD, - maskable: bool, - ) -> bool { - let input_definition = CString::new(input_definition).unwrap(); - - unsafe { - SimConnect_MapInputEventToClientEvent_EX1( - self.sim_connect_handle, - group_id, - input_definition.as_ptr(), - down_event, - down_return_value, - up_event, - up_return_value, - maskable as i32, - ) == 0 - } - } - - pub unsafe fn execute_action( - &self, - request_id: DWORD, - action_id: &str, - unit_size: DWORD, - param_values: *mut std::os::raw::c_void, - ) -> bool { - let action_id = CString::new(action_id).unwrap(); - unsafe { - SimConnect_ExecuteAction( - self.sim_connect_handle, - request_id, - action_id.as_ptr(), - unit_size, - param_values, - ) == 0 - } - } - - pub fn enumerate_input_events(&self, request_id: SIMCONNECT_DATA_REQUEST_ID) -> bool { - unsafe { SimConnect_EnumerateInputEvents(self.sim_connect_handle, request_id) == 0 } - } - - pub fn get_input_event(&self, request_id: SIMCONNECT_DATA_REQUEST_ID, hash: u64) -> bool { - unsafe { SimConnect_GetInputEvent(self.sim_connect_handle, request_id, hash) == 0 } - } - - pub unsafe fn set_input_event( - &self, - hash: u64, - unit_size: DWORD, - value: *mut std::os::raw::c_void, - ) -> bool { - unsafe { SimConnect_SetInputEvent(self.sim_connect_handle, hash, unit_size, value) == 0 } - } - - pub fn subscribe_input_event(&self, hash: u64) -> bool { - unsafe { SimConnect_SubscribeInputEvent(self.sim_connect_handle, hash) == 0 } - } - - pub fn unsubscribe_input_event(&self, hash: u64) -> bool { - unsafe { SimConnect_UnsubscribeInputEvent(self.sim_connect_handle, hash) == 0 } - } - - pub fn enumerate_input_event_params(&self, hash: u64) -> bool { - unsafe { SimConnect_EnumerateInputEventParams(self.sim_connect_handle, hash) == 0 } - } - - pub fn add_facility_data_definition_filter( - &self, - define_id: SIMCONNECT_DATA_DEFINITION_ID, - filter_path: &str, - filter_data: *const std::os::raw::c_void, - cb_unit_size: DWORD, - ) -> bool { - let filter_path = CString::new(filter_path).unwrap(); - unsafe { - SimConnect_AddFacilityDataDefinitionFilter( - self.sim_connect_handle, - define_id, - filter_path.as_ptr(), - cb_unit_size, - filter_data as *mut _, - ) == 0 - } - } - - pub fn clear_all_facility_data_definition_filters( - &self, - define_id: SIMCONNECT_DATA_DEFINITION_ID, - ) -> bool { - unsafe { - SimConnect_ClearAllFacilityDataDefinitionFilters(self.sim_connect_handle, define_id) - == 0 - } - } - - /// Retrieves the next message from SimConnect. Nonblocking. - pub fn get_next_message(&self) -> Result, &str> { - let mut data_buf: *mut SIMCONNECT_RECV = ptr::null_mut(); - let mut size_buf: DWORD = 0; - let size_buf_pointer: *mut DWORD = &mut size_buf; - - unsafe { - let result = SimConnect_GetNextDispatch( - self.sim_connect_handle, - &mut data_buf, - size_buf_pointer, - ); - - if result != 0 { - return Err("Failed getting data!"); - } - - // SimConnect_GetNextDispatch returns S_OK with a NULL pointer when the queue is empty. - // Dereferencing a null pointer would be UB, so we must check this explicitly. - if data_buf.is_null() { - return Ok(DispatchResult::Null); - } - - match (*data_buf).dwID as SIMCONNECT_RECV_ID { - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_NULL => Ok(DispatchResult::Null), - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EXCEPTION => Ok(DispatchResult::Exception( - transmute_copy(&(data_buf as *const SIMCONNECT_RECV_EXCEPTION)), - )), - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_OPEN => Ok(DispatchResult::Open( - transmute_copy(&(data_buf as *const SIMCONNECT_RECV_OPEN)), - )), - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_QUIT => Ok(DispatchResult::Quit( - transmute_copy(&(data_buf as *const SIMCONNECT_RECV_QUIT)), - )), - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT => Ok(DispatchResult::Event( - transmute_copy(&(data_buf as *const SIMCONNECT_RECV_EVENT)), - )), - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_OBJECT_ADDREMOVE => { - Ok(DispatchResult::EventObjectAddRemove(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_EVENT_OBJECT_ADDREMOVE), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_FILENAME => { - Ok(DispatchResult::EventFilename(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_EVENT_FILENAME), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_FRAME => { - Ok(DispatchResult::EventFrame(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_EVENT_FRAME), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_SIMOBJECT_DATA => { - Ok(DispatchResult::SimObjectData(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_SIMOBJECT_DATA), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_SIMOBJECT_DATA_BYTYPE => { - Ok(DispatchResult::SimObjectDataByType(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_SIMOBJECT_DATA_BYTYPE), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_WEATHER_OBSERVATION => { - Ok(DispatchResult::WeatherObservation(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_WEATHER_OBSERVATION), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_CLOUD_STATE => { - Ok(DispatchResult::CloudState(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_CLOUD_STATE), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_ASSIGNED_OBJECT_ID => { - Ok(DispatchResult::AssignedObjectId(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_ASSIGNED_OBJECT_ID), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_RESERVED_KEY => { - Ok(DispatchResult::ReservedKey(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_RESERVED_KEY), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_CUSTOM_ACTION => { - Ok(DispatchResult::CustomAction(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_CUSTOM_ACTION), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_SYSTEM_STATE => { - Ok(DispatchResult::SystemState(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_SYSTEM_STATE), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_CLIENT_DATA => { - Ok(DispatchResult::ClientData(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_CLIENT_DATA), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_WEATHER_MODE => { - Ok(DispatchResult::EventWeatherMode(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_EVENT_WEATHER_MODE), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_AIRPORT_LIST => { - Ok(DispatchResult::AirportList(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_AIRPORT_LIST), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_VOR_LIST => Ok(DispatchResult::VorList( - transmute_copy(&(data_buf as *const SIMCONNECT_RECV_VOR_LIST)), - )), - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_NDB_LIST => Ok(DispatchResult::NdbList( - transmute_copy(&(data_buf as *const SIMCONNECT_RECV_NDB_LIST)), - )), - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_WAYPOINT_LIST => { - Ok(DispatchResult::WaypointList(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_WAYPOINT_LIST), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_MULTIPLAYER_SERVER_STARTED => Ok( - DispatchResult::EventMultiplayerServerStarted(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_EVENT_MULTIPLAYER_SERVER_STARTED), - )), - ), - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_MULTIPLAYER_CLIENT_STARTED => Ok( - DispatchResult::EventMultiplayerClientStarted(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_EVENT_MULTIPLAYER_CLIENT_STARTED), - )), - ), - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_MULTIPLAYER_SESSION_ENDED => Ok( - DispatchResult::EventMultiplayerSessionEnded(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_EVENT_MULTIPLAYER_SESSION_ENDED), - )), - ), - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_RACE_END => { - Ok(DispatchResult::EventRaceEnd(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_EVENT_RACE_END), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_RACE_LAP => { - Ok(DispatchResult::EventRaceLap(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_EVENT_RACE_LAP), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT_EX1 => Ok(DispatchResult::EventEx1( - transmute_copy(&(data_buf as *const SIMCONNECT_RECV_EVENT_EX1)), - )), - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_FACILITY_DATA => { - Ok(DispatchResult::FacilityData(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_FACILITY_DATA), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_FACILITY_DATA_END => { - Ok(DispatchResult::FacilityDataEnd(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_FACILITY_DATA_END), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_FACILITY_MINIMAL_LIST => { - Ok(DispatchResult::FacilityMinimalList(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_FACILITY_MINIMAL_LIST), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_JETWAY_DATA => { - Ok(DispatchResult::JetwayData(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_JETWAY_DATA), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_CONTROLLERS_LIST => { - Ok(DispatchResult::ControllersList(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_CONTROLLERS_LIST), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_ACTION_CALLBACK => { - Ok(DispatchResult::ActionCallback(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_ACTION_CALLBACK), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_ENUMERATE_INPUT_EVENTS => { - Ok(DispatchResult::EnumerateInputEvents(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_ENUMERATE_INPUT_EVENTS), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_GET_INPUT_EVENT => { - Ok(DispatchResult::GetInputEvent(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_GET_INPUT_EVENT), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_SUBSCRIBE_INPUT_EVENT => { - Ok(DispatchResult::SubscribeInputEvent(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_SUBSCRIBE_INPUT_EVENT), - ))) - } - SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_ENUMERATE_INPUT_EVENT_PARAMS => { - Ok(DispatchResult::EnumerateInputEventParams(transmute_copy( - &(data_buf as *const SIMCONNECT_RECV_ENUMERATE_INPUT_EVENT_PARAMS), - ))) - } - - _ => Err("Unhandled RECV_ID"), - } - } - } -} - -impl Drop for SimConnector { - fn drop(&mut self) { - if !self.sim_connect_handle.is_null() { - self.close(); - } - } -} +#[cfg(feature = "fs2024")] +pub use simconnect_fs2024 as fs2024;