1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272
#![deny(missing_docs)]
//! # Lib Rail Driver
//!
//! Rust FFI bindings to the `RailDriver.dll` library.
//!
//! These allow you to read and write data to or from Train Simulator 2020. Note
//! that this doesn't work with Train Sim World.
//!
//! ## Quick example
//!
//! ```rust
//! extern crate libraildriver;
//!
//! fn main() {
//! let context = libraildriver::Context::new();
//! let speed = context.get_value(libraildriver::Value::Speedometer,
//! libraildriver::Kind::Current).expect("Failed to get value.");
//! println!("The train's current speed is: {}", speed);
//! }
//! ```
extern crate libraildriver_sys as libraildriver;
extern crate libc;
#[derive(Debug)]
/// The value you wish to target for an operation.
pub enum Value {
/// The current reverser setting (F/N/R).
/// Usually:
/// - `1`: F
/// - `0`: N
/// - `-1`: R
Reverser,
/// The current throttle setting, usually between `0` and `100`. For locomotives and units with
/// a separate throttle and brake control.
Throttle,
/// The current combined throttle/brake setting, usually between `-100` and `100`. For
/// locomotives and units with a combined throttle and brake.
CombinedThrottle,
/// The current gear, for trains fitted.
GearLever,
/// The train brake lever. Usually between `0` and `100`.
TrainBrake,
/// The locomotive brake lever. Usually between `0` and `100`.
LocomotiveBrake,
/// The dynamic brake lever. Usually between `0` and `100`.
DynamicBrake,
/// The emergency brake button. Usually operated by setting to `1`.
EmergencyBrake,
/// The hand brake. Usually operated by setting to `1`.
HandBrake,
/// The warning system reset button. Usually operated by setting to `1`.
WarningSystemReset,
/// The engine start/stop button. Usually operated by setting to `1`.
StartStopEngine,
/// The horn lever. Usually operated by setting to `1`.
Horn,
/// The wipers switch. Usually operated by setting to `1`.
Wipers,
/// The sander. Usually operated by setting to `1`.
Sander,
/// The headlights. Often operated by setting to `1`.
Headlights,
/// The pantograph switch. Usually raised by setting to `1`.
Pantograph,
/// The firebox door. Usually opened by setting to `1`.
FireboxDoor,
/// The exhaust-based steam injector. Usually between `0` and `100`.
ExhaustInjectorSteam,
/// The exhaust-based water injector. Usually between `0` and `100`.
ExhaustInjectorWater,
/// The live steam injector. Usually between `0` and `100`.
LiveInjectorSteam,
/// The live water injector. Usually between `0` and `100`.
LiveInjectorWater,
/// The damper. Usually actuated between `0` and `100`.
Damper,
/// The blower valve. Usually opened between `0` and `100`.
Blower,
/// Stoking. Usually stoking when set to `1`.
Stoking,
/// The cylinder cocks. Usually opened when set to `1`.
CylinderCock,
/// The waterscoop. Usually operated when set to `1`.
Waterscoop,
/// Currently undocumented.
SmallCompressor,
/// Get only: The state of the AWS.
AWS,
/// Set only: The AWS reset button, depressed when set to `1`.
AWSReset,
/// Whether the unit is in startup
// TODO: Verify this
Startup,
/// Get only: The current speed of the unit.
Speedometer,
// Events
/// The save event, usually triggered by `F2`, triggered when set to `1`.
PromptSave,
/// Toggle labels, triggered when set to `1`.
// TODO: Check if this is toggled or enabled.
ToggleLabels,
/// The 2D Map, usually triggered by `9`, triggered when set to `1`.
Toggle2DMap,
/// Toggle the HUD visibilty, usually triggered by `F3` or `F4`, triggered when set to `1`.
ToggleHud,
/// Currently undocumented.
ToggleQut,
/// Pause the game, triggered when set to `1`.
Pause,
/// Currently undocumented.
DriverGuide,
/// Show the rail vehicle number, enabled when set to `1`.
// TODO: Check whether this is enabled or toggled.
ToggleRvNumber,
/// Close the dialog given to you by an assignment in a scenario.
DialogAssignment,
/// Switch the set of points to the front of the train, triggered when set to `1`.
SwitchJunctionAhead,
/// Switch the set of points to the rear of the train, triggered when set to `1`.
SwitchJunctionBehind,
/// The load cargo event, triggered when set to `1`.
LoadCargo,
/// The unload cargo action, triggered when set to `1`.
UnloadCargo,
/// Request to pass a signal at danger to the front of the train, usually triggered by `Tab`,
/// triggered when set to `1`.
PassAtDangerAhead,
/// Request to pass a signal at danger to the rear of the train, usually triggered by
/// `Shift Tab`, triggered when set to `1`.
PassAtDangerBehind,
/// Manual coupling, triggered when set to `1`.
ManualCouple,
// Camera
/// The cab camera, usually operated by pressing `1`, switched to by setting to `1`.
CabCamera,
/// The follow camera, usually operated by pressing `2`, switched to by setting to `1`.
FollowCamera,
/// The head-out-window camera, usually operated by pressing `Shift 2`, switched to by setting
/// to `1`.
HeadOutCamera,
/// The rear camera, usually operated by pressing `3`, switched to by setting to `1`.
RearCamera,
/// The track-side camera, usually operated by pressing `4`, switched to by setting to `1`.
TrackSideCamera,
/// The passenger-view (carriage) camera, usually operated by pressing `5`, switched to by
/// setting to `1`.
CarriageCamera,
/// The coupling camera, usually operated by pressing `6`, switched to by setting to `1`.
CouplingCamera,
/// The yard camera, usually operated by pressing `7`, switched to by setting to `1`.
YardCamera,
/// Cab camera switch, usually operated by pressing `Ctrl +`, switched to by setting to `1`.
SwitchToNextFrontCab,
/// Cab camera switch, usually operated by pressing `Ctrl -`, switched to by setting to `1`.
SwitchToNextRearCab,
/// The free camera, usually operated by pressing `8`, switched to by setting to `1`.
FreeCamera,
}
/// The value of data supposedly from the controller, although RailDriver does offer some
/// 'virtual' values.
#[derive(Debug)]
pub enum ControllerValue {
/// Latitude of the player
Latitude = 400,
/// Longitude of the player
Longitude,
/// Fuel level of the train
FuelLevel,
/// Is the train in a tunnel
InTunnel,
/// Gradient of the track
Gradient,
/// Heading of the player
Heading,
/// Time of day, hour component
TimeHours,
/// Time of day, minute component
TimeMinutes,
/// Time of day, second component
TimeSeconds,
}
#[derive(Debug)]
/// The kind of value that is required
pub enum Kind {
/// The current value
Current,
/// The minimum value
Min,
/// The maximum value
Max,
}
/// A custom `Result` type to simplify dealing with errors.
pub type Result<T> = std::result::Result<T, RailDriverError>;
#[derive(Debug)]
/// Errors returned by the operation being performed.
pub enum RailDriverError {
/// The simulator doens't think this context is connected, therefore the operation cannot
/// continue.
NotConnected,
}
/// A controller context with the simulator.
pub struct Context {
connected: bool,
}
impl Drop for Context {
fn drop(&mut self) {
self.disconnect();
}
}
impl Context {
/// Creates a new controller context with the simulator.
pub fn new() -> Self {
let mut val = Self {
connected: false,
};
val.connect();
val
}
fn connect(&mut self) {
unsafe { libraildriver::SetRailDriverConnected(true); }
self.connected = true;
}
fn disconnect(&mut self) {
unsafe { libraildriver::SetRailDriverConnected(false); }
self.connected = false;
}
/// Return the value of `of`. Depending on `kind`, this may return the current value, a
/// minimum, or a maximum.
pub fn get_value(&self, of: Value, kind: Kind) -> Result<f32> {
if !self.connected {
return Err(RailDriverError::NotConnected);
}
let of = of as libc::c_int;
let kind = kind as libc::c_int;
unsafe { Ok(libraildriver::GetRailSimValue(of, kind)) }
}
/// Set the value of `of` within the simulator to `value`.
pub fn set_value(&self, of: Value, value: i32) -> Result<()> {
if !self.connected {
return Err(RailDriverError::NotConnected);
}
let of = of as libc::c_int;
let value = value as libc::c_int;
unsafe { libraildriver::SetRailSimValue(of, value); }
Ok(())
}
/// Return the value of `of` from the virtual controller. Depending on `kind`, this may
/// return the current value, a minimum, or a maximum.
pub fn get_controller_value(&self, of: ControllerValue, kind: Kind) -> Result<f32> {
if !self.connected {
return Err(RailDriverError::NotConnected);
}
let of = of as libc::c_int;
let kind = kind as libc::c_int;
unsafe { Ok(libraildriver::GetControllerValue(of, kind)) }
}
}